new structure
This commit is contained in:
parent
a0f3d0edd7
commit
46df6b9e62
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
||||||
*pyc
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
# This file must be used with "source bin/activate" *from bash*
|
|
||||||
# you cannot run it directly
|
|
||||||
|
|
||||||
deactivate () {
|
|
||||||
# reset old environment variables
|
|
||||||
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
|
|
||||||
PATH="${_OLD_VIRTUAL_PATH:-}"
|
|
||||||
export PATH
|
|
||||||
unset _OLD_VIRTUAL_PATH
|
|
||||||
fi
|
|
||||||
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
|
|
||||||
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
|
|
||||||
export PYTHONHOME
|
|
||||||
unset _OLD_VIRTUAL_PYTHONHOME
|
|
||||||
fi
|
|
||||||
|
|
||||||
# This should detect bash and zsh, which have a hash command that must
|
|
||||||
# be called to get it to forget past commands. Without forgetting
|
|
||||||
# past commands the $PATH changes we made may not be respected
|
|
||||||
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
|
||||||
hash -r
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
|
|
||||||
PS1="${_OLD_VIRTUAL_PS1:-}"
|
|
||||||
export PS1
|
|
||||||
unset _OLD_VIRTUAL_PS1
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset VIRTUAL_ENV
|
|
||||||
if [ ! "$1" = "nondestructive" ] ; then
|
|
||||||
# Self destruct!
|
|
||||||
unset -f deactivate
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# unset irrelevant variables
|
|
||||||
deactivate nondestructive
|
|
||||||
|
|
||||||
VIRTUAL_ENV="/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv"
|
|
||||||
export VIRTUAL_ENV
|
|
||||||
|
|
||||||
_OLD_VIRTUAL_PATH="$PATH"
|
|
||||||
PATH="$VIRTUAL_ENV/bin:$PATH"
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
# unset PYTHONHOME if set
|
|
||||||
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
|
||||||
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
|
||||||
if [ -n "${PYTHONHOME:-}" ] ; then
|
|
||||||
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
|
|
||||||
unset PYTHONHOME
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
|
||||||
_OLD_VIRTUAL_PS1="${PS1:-}"
|
|
||||||
if [ "x(.venv) " != x ] ; then
|
|
||||||
PS1="(.venv) ${PS1:-}"
|
|
||||||
else
|
|
||||||
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
|
|
||||||
# special case for Aspen magic directories
|
|
||||||
# see http://www.zetadev.com/software/aspen/
|
|
||||||
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
|
|
||||||
else
|
|
||||||
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
export PS1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# This should detect bash and zsh, which have a hash command that must
|
|
||||||
# be called to get it to forget past commands. Without forgetting
|
|
||||||
# past commands the $PATH changes we made may not be respected
|
|
||||||
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
|
|
||||||
hash -r
|
|
||||||
fi
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
# This file must be used with "source bin/activate.csh" *from csh*.
|
|
||||||
# You cannot run it directly.
|
|
||||||
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
|
||||||
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
|
|
||||||
|
|
||||||
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate'
|
|
||||||
|
|
||||||
# Unset irrelevant variables.
|
|
||||||
deactivate nondestructive
|
|
||||||
|
|
||||||
setenv VIRTUAL_ENV "/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv"
|
|
||||||
|
|
||||||
set _OLD_VIRTUAL_PATH="$PATH"
|
|
||||||
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
|
|
||||||
|
|
||||||
|
|
||||||
set _OLD_VIRTUAL_PROMPT="$prompt"
|
|
||||||
|
|
||||||
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
|
|
||||||
if (".venv" != "") then
|
|
||||||
set env_name = ".venv"
|
|
||||||
else
|
|
||||||
if (`basename "VIRTUAL_ENV"` == "__") then
|
|
||||||
# special case for Aspen magic directories
|
|
||||||
# see http://www.zetadev.com/software/aspen/
|
|
||||||
set env_name = `basename \`dirname "$VIRTUAL_ENV"\``
|
|
||||||
else
|
|
||||||
set env_name = `basename "$VIRTUAL_ENV"`
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
set prompt = "[$env_name] $prompt"
|
|
||||||
unset env_name
|
|
||||||
endif
|
|
||||||
|
|
||||||
alias pydoc python -m pydoc
|
|
||||||
|
|
||||||
rehash
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org)
|
|
||||||
# you cannot run it directly
|
|
||||||
|
|
||||||
function deactivate -d "Exit virtualenv and return to normal shell environment"
|
|
||||||
# reset old environment variables
|
|
||||||
if test -n "$_OLD_VIRTUAL_PATH"
|
|
||||||
set -gx PATH $_OLD_VIRTUAL_PATH
|
|
||||||
set -e _OLD_VIRTUAL_PATH
|
|
||||||
end
|
|
||||||
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
|
||||||
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
|
|
||||||
set -e _OLD_VIRTUAL_PYTHONHOME
|
|
||||||
end
|
|
||||||
|
|
||||||
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
|
||||||
functions -e fish_prompt
|
|
||||||
set -e _OLD_FISH_PROMPT_OVERRIDE
|
|
||||||
functions -c _old_fish_prompt fish_prompt
|
|
||||||
functions -e _old_fish_prompt
|
|
||||||
end
|
|
||||||
|
|
||||||
set -e VIRTUAL_ENV
|
|
||||||
if test "$argv[1]" != "nondestructive"
|
|
||||||
# Self destruct!
|
|
||||||
functions -e deactivate
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# unset irrelevant variables
|
|
||||||
deactivate nondestructive
|
|
||||||
|
|
||||||
set -gx VIRTUAL_ENV "/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv"
|
|
||||||
|
|
||||||
set -gx _OLD_VIRTUAL_PATH $PATH
|
|
||||||
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
|
|
||||||
|
|
||||||
# unset PYTHONHOME if set
|
|
||||||
if set -q PYTHONHOME
|
|
||||||
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
|
||||||
set -e PYTHONHOME
|
|
||||||
end
|
|
||||||
|
|
||||||
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
|
||||||
# fish uses a function instead of an env var to generate the prompt.
|
|
||||||
|
|
||||||
# save the current fish_prompt function as the function _old_fish_prompt
|
|
||||||
functions -c fish_prompt _old_fish_prompt
|
|
||||||
|
|
||||||
# with the original prompt function renamed, we can override with our own.
|
|
||||||
function fish_prompt
|
|
||||||
# Save the return status of the last command
|
|
||||||
set -l old_status $status
|
|
||||||
|
|
||||||
# Prompt override?
|
|
||||||
if test -n "(.venv) "
|
|
||||||
printf "%s%s" "(.venv) " (set_color normal)
|
|
||||||
else
|
|
||||||
# ...Otherwise, prepend env
|
|
||||||
set -l _checkbase (basename "$VIRTUAL_ENV")
|
|
||||||
if test $_checkbase = "__"
|
|
||||||
# special case for Aspen magic directories
|
|
||||||
# see http://www.zetadev.com/software/aspen/
|
|
||||||
printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal)
|
|
||||||
else
|
|
||||||
printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Restore the return status of the previous command.
|
|
||||||
echo "exit $old_status" | .
|
|
||||||
_old_fish_prompt
|
|
||||||
end
|
|
||||||
|
|
||||||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
|
||||||
end
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from setuptools.command.easy_install import main
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from setuptools.command.easy_install import main
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python
|
|
||||||
# -*- 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,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python
|
|
||||||
# -*- 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())
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from pip._internal import main
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from pip._internal import main
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from pip._internal import main
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python
|
|
||||||
# -*- 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())
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python
|
|
||||||
# -*- 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())
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
python3
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/usr/bin/python3
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/home/rusticus/Dokumente/Windmessanlage/Software/Display/.venv/bin/python
|
|
||||||
# -*- 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,27 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CAMERA_H
|
|
||||||
#define _CAMERA_H
|
|
||||||
|
|
||||||
#include "_pygame.h"
|
|
||||||
#include "camera.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,239 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This will use PYGAMEAPI_EXTERN_SLOTS instead
|
|
||||||
* of PYGAMEAPI_DEFINE_SLOTS for base modules.
|
|
||||||
*/
|
|
||||||
#ifndef _PYGAME_INTERNAL_H
|
|
||||||
#define _PYGAME_INTERNAL_H
|
|
||||||
|
|
||||||
#include "pgplatform.h"
|
|
||||||
#include <Python.h>
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
/* IS_SDLv1 is 1 if SDL 1.x.x, 0 otherwise */
|
|
||||||
/* IS_SDLv2 is 1 if at least SDL 2.0.0, 0 otherwise */
|
|
||||||
#if (SDL_VERSION_ATLEAST(2, 0, 0))
|
|
||||||
#define IS_SDLv2 1
|
|
||||||
#define IS_SDLv1 0
|
|
||||||
#else
|
|
||||||
#define IS_SDLv2 0
|
|
||||||
#define IS_SDLv1 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*#if IS_SDLv1 && PG_MAJOR_VERSION >= 2
|
|
||||||
#error pygame 2 requires SDL 2
|
|
||||||
#endif*/
|
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
/* SDL 1.2 constants removed from SDL 2 */
|
|
||||||
typedef enum {
|
|
||||||
SDL_HWSURFACE = 0,
|
|
||||||
SDL_RESIZABLE = SDL_WINDOW_RESIZABLE,
|
|
||||||
SDL_ASYNCBLIT = 0,
|
|
||||||
SDL_OPENGL = SDL_WINDOW_OPENGL,
|
|
||||||
SDL_OPENGLBLIT = 0,
|
|
||||||
SDL_ANYFORMAT = 0,
|
|
||||||
SDL_HWPALETTE = 0,
|
|
||||||
SDL_DOUBLEBUF = 0,
|
|
||||||
SDL_FULLSCREEN = SDL_WINDOW_FULLSCREEN,
|
|
||||||
SDL_HWACCEL = 0,
|
|
||||||
SDL_SRCCOLORKEY = 0,
|
|
||||||
SDL_RLEACCELOK = 0,
|
|
||||||
SDL_SRCALPHA = 0,
|
|
||||||
SDL_NOFRAME = SDL_WINDOW_BORDERLESS,
|
|
||||||
SDL_GL_SWAP_CONTROL = 0,
|
|
||||||
TIMER_RESOLUTION = 0
|
|
||||||
} PygameVideoFlags;
|
|
||||||
|
|
||||||
/* the wheel button constants were removed from SDL 2 */
|
|
||||||
typedef enum {
|
|
||||||
PGM_BUTTON_LEFT = SDL_BUTTON_LEFT,
|
|
||||||
PGM_BUTTON_RIGHT = SDL_BUTTON_RIGHT,
|
|
||||||
PGM_BUTTON_MIDDLE = SDL_BUTTON_MIDDLE,
|
|
||||||
PGM_BUTTON_WHEELUP = 4,
|
|
||||||
PGM_BUTTON_WHEELDOWN = 5,
|
|
||||||
PGM_BUTTON_X1 = SDL_BUTTON_X1 + 2,
|
|
||||||
PGM_BUTTON_X2 = SDL_BUTTON_X2 + 2,
|
|
||||||
PGM_BUTTON_KEEP = 0x80
|
|
||||||
} PygameMouseFlags;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* Any SDL_* events here are for backward compatibility. */
|
|
||||||
SDL_NOEVENT = 0,
|
|
||||||
|
|
||||||
/* pygame events */
|
|
||||||
PGE_EVENTBEGIN = SDL_USEREVENT, /* Not an event. Indicates start of pygame events. */
|
|
||||||
SDL_ACTIVEEVENT = PGE_EVENTBEGIN,
|
|
||||||
SDL_VIDEORESIZE,
|
|
||||||
SDL_VIDEOEXPOSE,
|
|
||||||
PGE_KEYREPEAT,
|
|
||||||
PGE_MIDIIN,
|
|
||||||
PGE_MIDIOUT,
|
|
||||||
PGE_EVENTEND, /* Not an event. Indicates end of pygame events. */
|
|
||||||
|
|
||||||
/* User event range. */
|
|
||||||
/* SDL 1.2 allowed for 8 user defined events. */
|
|
||||||
PGE_USEREVENT = PGE_EVENTEND,
|
|
||||||
PG_NUMEVENTS = PGE_USEREVENT + 0x2000 /* Not an event. Indicates end of user events. */
|
|
||||||
} PygameEventCode;
|
|
||||||
|
|
||||||
#define PGE_NUMRESERVED (PGE_EVENTEND - PGE_EVENTBEGIN)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SDL_APPFOCUSMOUSE,
|
|
||||||
SDL_APPINPUTFOCUS,
|
|
||||||
SDL_APPACTIVE
|
|
||||||
} PygameAppCode;
|
|
||||||
|
|
||||||
/* Surface flags: based on SDL 1.2 flags */
|
|
||||||
typedef enum {
|
|
||||||
PGS_SWSURFACE = 0x00000000,
|
|
||||||
PGS_HWSURFACE = 0x00000001,
|
|
||||||
PGS_ASYNCBLIT = 0x00000004,
|
|
||||||
|
|
||||||
PGS_ANYFORMAT = 0x10000000,
|
|
||||||
PGS_HWPALETTE = 0x20000000,
|
|
||||||
PGS_DOUBLEBUF = 0x40000000,
|
|
||||||
PGS_FULLSCREEN = 0x80000000,
|
|
||||||
PGS_SCALED = 0x00000200,
|
|
||||||
|
|
||||||
PGS_OPENGL = 0x00000002,
|
|
||||||
PGS_OPENGLBLIT = 0x0000000A,
|
|
||||||
PGS_RESIZABLE = 0x00000010,
|
|
||||||
PGS_NOFRAME = 0x00000020,
|
|
||||||
PGS_SHOWN = 0x00000040, /* Added from SDL 2 */
|
|
||||||
PGS_HIDDEN = 0x00000080, /* Added from SDL 2 */
|
|
||||||
|
|
||||||
PGS_HWACCEL = 0x00000100,
|
|
||||||
PGS_SRCCOLORKEY = 0x00001000,
|
|
||||||
PGS_RLEACCELOK = 0x00002000,
|
|
||||||
PGS_RLEACCEL = 0x00004000,
|
|
||||||
PGS_SRCALPHA = 0x00010000,
|
|
||||||
PGS_PREALLOC = 0x01000000
|
|
||||||
} PygameSurfaceFlags;
|
|
||||||
#else /* ~SDL_VERSION_ATLEAST(2, 0, 0) */
|
|
||||||
/* To maintain SDL 1.2 build support. */
|
|
||||||
#define PGE_USEREVENT SDL_USEREVENT
|
|
||||||
#define PG_NUMEVENTS SDL_NUMEVENTS
|
|
||||||
/* These midi events were originally defined in midi.py.
|
|
||||||
* Note: They are outside the SDL_USEREVENT/SDL_NUMEVENTS event range for
|
|
||||||
* SDL 1.2. */
|
|
||||||
#define PGE_MIDIIN PGE_USEREVENT + 10
|
|
||||||
#define PGE_MIDIOUT PGE_USEREVENT + 11
|
|
||||||
#endif /* ~SDL_VERSION_ATLEAST(2, 0, 0) */
|
|
||||||
|
|
||||||
#define RAISE(x, y) (PyErr_SetString((x), (y)), (PyObject *)NULL)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialization checks
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VIDEO_INIT_CHECK() \
|
|
||||||
if (!SDL_WasInit(SDL_INIT_VIDEO)) \
|
|
||||||
return RAISE(pgExc_SDLError, "video system not initialized")
|
|
||||||
|
|
||||||
#define CDROM_INIT_CHECK() \
|
|
||||||
if (!SDL_WasInit(SDL_INIT_CDROM)) \
|
|
||||||
return RAISE(pgExc_SDLError, "cdrom system not initialized")
|
|
||||||
|
|
||||||
#define JOYSTICK_INIT_CHECK() \
|
|
||||||
if (!SDL_WasInit(SDL_INIT_JOYSTICK)) \
|
|
||||||
return RAISE(pgExc_SDLError, "joystick system not initialized")
|
|
||||||
|
|
||||||
/* thread check */
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
#define PG_CHECK_THREADS() (1)
|
|
||||||
#else /* ~WITH_THREAD */
|
|
||||||
#define PG_CHECK_THREADS() \
|
|
||||||
(RAISE(PyExc_NotImplementedError, \
|
|
||||||
"Python built without thread support"))
|
|
||||||
#endif /* ~WITH_THREAD */
|
|
||||||
|
|
||||||
#define PyType_Init(x) (((x).ob_type) = &PyType_Type)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* event module internals
|
|
||||||
*/
|
|
||||||
struct pgEventObject {
|
|
||||||
PyObject_HEAD int type;
|
|
||||||
PyObject *dict;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* surflock module internals
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD PyObject *surface;
|
|
||||||
PyObject *lockobj;
|
|
||||||
PyObject *weakrefs;
|
|
||||||
} pgLifetimeLockObject;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* surface module internals
|
|
||||||
*/
|
|
||||||
struct pgSubSurface_Data {
|
|
||||||
PyObject *owner;
|
|
||||||
int pixeloffset;
|
|
||||||
int offsetx, offsety;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* color module internals
|
|
||||||
*/
|
|
||||||
struct pgColorObject {
|
|
||||||
PyObject_HEAD
|
|
||||||
Uint8 data[4];
|
|
||||||
Uint8 len;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* include public API
|
|
||||||
*/
|
|
||||||
#include "include/_pygame.h"
|
|
||||||
|
|
||||||
#include "pgimport.h"
|
|
||||||
|
|
||||||
/* Slot counts.
|
|
||||||
* Remember to keep these constants up to date.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PYGAMEAPI_RECT_NUMSLOTS 4
|
|
||||||
#define PYGAMEAPI_JOYSTICK_NUMSLOTS 2
|
|
||||||
#define PYGAMEAPI_DISPLAY_NUMSLOTS 2
|
|
||||||
#define PYGAMEAPI_SURFACE_NUMSLOTS 4
|
|
||||||
#define PYGAMEAPI_SURFLOCK_NUMSLOTS 8
|
|
||||||
#define PYGAMEAPI_RWOBJECT_NUMSLOTS 6
|
|
||||||
#define PYGAMEAPI_PIXELARRAY_NUMSLOTS 2
|
|
||||||
#define PYGAMEAPI_COLOR_NUMSLOTS 5
|
|
||||||
#define PYGAMEAPI_MATH_NUMSLOTS 2
|
|
||||||
#define PYGAMEAPI_CDROM_NUMSLOTS 2
|
|
||||||
|
|
||||||
#if PG_API_VERSION == 1
|
|
||||||
#define PYGAMEAPI_BASE_NUMSLOTS 19
|
|
||||||
#define PYGAMEAPI_EVENT_NUMSLOTS 4
|
|
||||||
#else /* PG_API_VERSION == 2 */
|
|
||||||
#define PYGAMEAPI_BASE_NUMSLOTS 23
|
|
||||||
#define PYGAMEAPI_EVENT_NUMSLOTS 6
|
|
||||||
#endif /* PG_API_VERSION == 2 */
|
|
||||||
|
|
||||||
#endif /* _PYGAME_INTERNAL_H */
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
Copyright (C) 2007 Marcus von Appen
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SURFACE_H
|
|
||||||
#define _SURFACE_H
|
|
||||||
|
|
||||||
#include "_pygame.h"
|
|
||||||
#include "surface.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,205 +0,0 @@
|
||||||
#ifndef CAMERA_H
|
|
||||||
#define CAMERA_H
|
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pygame.h"
|
|
||||||
#include "doc/camera_doc.h"
|
|
||||||
|
|
||||||
#if defined(__unix__)
|
|
||||||
#include <structmember.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <fcntl.h> /* low-level i/o */
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
/* on freebsd there is no asm/types */
|
|
||||||
#ifdef linux
|
|
||||||
#include <asm/types.h> /* for videodev2.h */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <linux/videodev2.h>
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#include <AvailabilityMacros.h>
|
|
||||||
/* We support OSX 10.6 and below. */
|
|
||||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1060
|
|
||||||
#define PYGAME_MAC_CAMERA_OLD 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PYGAME_MAC_CAMERA_OLD)
|
|
||||||
#include <QuickTime/QuickTime.h>
|
|
||||||
#include <QuickTime/Movies.h>
|
|
||||||
#include <QuickTime/ImageCompression.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* some constants used which are not defined on non-v4l machines. */
|
|
||||||
#ifndef V4L2_PIX_FMT_RGB24
|
|
||||||
#define V4L2_PIX_FMT_RGB24 'RGB3'
|
|
||||||
#endif
|
|
||||||
#ifndef V4L2_PIX_FMT_RGB444
|
|
||||||
#define V4L2_PIX_FMT_RGB444 'R444'
|
|
||||||
#endif
|
|
||||||
#ifndef V4L2_PIX_FMT_YUYV
|
|
||||||
#define V4L2_PIX_FMT_YUYV 'YUYV'
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CLEAR(x) memset (&(x), 0, sizeof (x))
|
|
||||||
#define SAT(c) if (c & (~255)) { if (c < 0) c = 0; else c = 255; }
|
|
||||||
#define SAT2(c) ((c) & (~255) ? ((c) < 0 ? 0 : 255) : (c))
|
|
||||||
#define DEFAULT_WIDTH 640
|
|
||||||
#define DEFAULT_HEIGHT 480
|
|
||||||
#define RGB_OUT 1
|
|
||||||
#define YUV_OUT 2
|
|
||||||
#define HSV_OUT 4
|
|
||||||
#define CAM_V4L 1 /* deprecated. the incomplete support in pygame was removed */
|
|
||||||
#define CAM_V4L2 2
|
|
||||||
|
|
||||||
struct buffer {
|
|
||||||
void * start;
|
|
||||||
size_t length;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(__unix__)
|
|
||||||
typedef struct pgCameraObject {
|
|
||||||
PyObject_HEAD
|
|
||||||
char* device_name;
|
|
||||||
int camera_type;
|
|
||||||
unsigned long pixelformat;
|
|
||||||
unsigned int color_out;
|
|
||||||
struct buffer* buffers;
|
|
||||||
unsigned int n_buffers;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int size;
|
|
||||||
int hflip;
|
|
||||||
int vflip;
|
|
||||||
int brightness;
|
|
||||||
int fd;
|
|
||||||
} pgCameraObject;
|
|
||||||
#elif defined(PYGAME_MAC_CAMERA_OLD)
|
|
||||||
typedef struct pgCameraObject {
|
|
||||||
PyObject_HEAD
|
|
||||||
char* device_name; /* unique name of the device */
|
|
||||||
OSType pixelformat;
|
|
||||||
unsigned int color_out;
|
|
||||||
SeqGrabComponent component; /* A type used by the Sequence Grabber API */
|
|
||||||
SGChannel channel; /* Channel of the Sequence Grabber */
|
|
||||||
GWorldPtr gworld; /* Pointer to the struct that holds the data of the captured image */
|
|
||||||
Rect boundsRect; /* bounds of the image frame */
|
|
||||||
long size; /* size of the image in our buffer to draw */
|
|
||||||
int hflip;
|
|
||||||
int vflip;
|
|
||||||
short depth;
|
|
||||||
struct buffer pixels;
|
|
||||||
//struct buffer tmp_pixels /* place where the flipped image in temporarily stored if hflip or vflip is true.*/
|
|
||||||
} pgCameraObject;
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* generic definition.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct pgCameraObject {
|
|
||||||
PyObject_HEAD
|
|
||||||
char* device_name;
|
|
||||||
int camera_type;
|
|
||||||
unsigned long pixelformat;
|
|
||||||
unsigned int color_out;
|
|
||||||
struct buffer* buffers;
|
|
||||||
unsigned int n_buffers;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int size;
|
|
||||||
int hflip;
|
|
||||||
int vflip;
|
|
||||||
int brightness;
|
|
||||||
int fd;
|
|
||||||
} pgCameraObject;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* internal functions for colorspace conversion */
|
|
||||||
void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace);
|
|
||||||
void rgb24_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format);
|
|
||||||
void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format);
|
|
||||||
void rgb_to_yuv (const void* src, void* dst, int length,
|
|
||||||
unsigned long source, SDL_PixelFormat* format);
|
|
||||||
void rgb_to_hsv (const void* src, void* dst, int length,
|
|
||||||
unsigned long source, SDL_PixelFormat* format);
|
|
||||||
void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format);
|
|
||||||
void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format);
|
|
||||||
void uyvy_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format);
|
|
||||||
void uyvy_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format);
|
|
||||||
void sbggr8_to_rgb (const void* src, void* dst, int width, int height,
|
|
||||||
SDL_PixelFormat* format);
|
|
||||||
void yuv420_to_rgb (const void* src, void* dst, int width, int height,
|
|
||||||
SDL_PixelFormat* format);
|
|
||||||
void yuv420_to_yuv (const void* src, void* dst, int width, int height,
|
|
||||||
SDL_PixelFormat* format);
|
|
||||||
|
|
||||||
#if defined(__unix__)
|
|
||||||
/* internal functions specific to v4l2 */
|
|
||||||
char** v4l2_list_cameras (int* num_devices);
|
|
||||||
int v4l2_get_control (int fd, int id, int *value);
|
|
||||||
int v4l2_set_control (int fd, int id, int value);
|
|
||||||
PyObject* v4l2_read_raw (pgCameraObject* self);
|
|
||||||
int v4l2_xioctl (int fd, int request, void *arg);
|
|
||||||
int v4l2_process_image (pgCameraObject* self, const void *image,
|
|
||||||
unsigned int buffer_size, SDL_Surface* surf);
|
|
||||||
int v4l2_query_buffer (pgCameraObject* self);
|
|
||||||
int v4l2_read_frame (pgCameraObject* self, SDL_Surface* surf);
|
|
||||||
int v4l2_stop_capturing (pgCameraObject* self);
|
|
||||||
int v4l2_start_capturing (pgCameraObject* self);
|
|
||||||
int v4l2_uninit_device (pgCameraObject* self);
|
|
||||||
int v4l2_init_mmap (pgCameraObject* self);
|
|
||||||
int v4l2_init_device (pgCameraObject* self);
|
|
||||||
int v4l2_close_device (pgCameraObject* self);
|
|
||||||
int v4l2_open_device (pgCameraObject* self);
|
|
||||||
|
|
||||||
#elif defined(PYGAME_MAC_CAMERA_OLD)
|
|
||||||
/* internal functions specific to mac */
|
|
||||||
char** mac_list_cameras(int* num_devices);
|
|
||||||
int mac_open_device (pgCameraObject* self);
|
|
||||||
int mac_init_device(pgCameraObject* self);
|
|
||||||
int mac_close_device (pgCameraObject* self);
|
|
||||||
int mac_start_capturing(pgCameraObject* self);
|
|
||||||
int mac_stop_capturing (pgCameraObject* self);
|
|
||||||
|
|
||||||
int mac_get_control(pgCameraObject* self, int id, int* value);
|
|
||||||
int mac_set_control(pgCameraObject* self, int id, int value);
|
|
||||||
|
|
||||||
PyObject* mac_read_raw(pgCameraObject *self);
|
|
||||||
int mac_read_frame(pgCameraObject* self, SDL_Surface* surf);
|
|
||||||
int mac_camera_idle(pgCameraObject* self);
|
|
||||||
int mac_copy_gworld_to_surface(pgCameraObject* self, SDL_Surface* surf);
|
|
||||||
|
|
||||||
void flip_image(const void* image, void* flipped_image, int width, int height,
|
|
||||||
short depth, int hflip, int vflip);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !CAMERA_H */
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
#ifndef _FASTEVENTS_H_
|
|
||||||
#define _FASTEVENTS_H_
|
|
||||||
/*
|
|
||||||
NET2 is a threaded, event based, network IO library for SDL.
|
|
||||||
Copyright (C) 2002 Bob Pendleton
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2.1
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
||||||
02111-1307 USA
|
|
||||||
|
|
||||||
If you do not wish to comply with the terms of the LGPL please
|
|
||||||
contact the author as other terms are available for a fee.
|
|
||||||
|
|
||||||
Bob Pendleton
|
|
||||||
Bob@Pendleton.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "SDL.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int FE_Init(void); // Initialize FE
|
|
||||||
void FE_Quit(void); // shutdown FE
|
|
||||||
|
|
||||||
void FE_PumpEvents(void); // replacement for SDL_PumpEvents
|
|
||||||
int FE_PollEvent(SDL_Event *event); // replacement for SDL_PollEvent
|
|
||||||
int FE_WaitEvent(SDL_Event *event); // replacement for SDL_WaitEvent
|
|
||||||
int FE_PushEvent(SDL_Event *event); // replacement for SDL_PushEvent
|
|
||||||
|
|
||||||
char *FE_GetError(void); // get the last error
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef PGFONT_INTERNAL_H
|
|
||||||
#define PGFONT_INTERNAL_H
|
|
||||||
|
|
||||||
#include <SDL_ttf.h>
|
|
||||||
|
|
||||||
/* test font initialization */
|
|
||||||
#define FONT_INIT_CHECK() \
|
|
||||||
if(!(*(int*)PyFONT_C_API[2])) \
|
|
||||||
return RAISE(pgExc_SDLError, "font system not initialized")
|
|
||||||
|
|
||||||
#include "include/pygame_font.h"
|
|
||||||
|
|
||||||
#define PYGAMEAPI_FONT_NUMSLOTS 3
|
|
||||||
|
|
||||||
#endif /* ~PGFONT_INTERNAL_H */
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2009 Vicent Marti
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef _PYGAME_FREETYPE_INTERNAL_H_
|
|
||||||
#define _PYGAME_FREETYPE_INTERNAL_H_
|
|
||||||
|
|
||||||
#define PGFT_PYGAME1_COMPAT
|
|
||||||
#define HAVE_PYGAME_SDL_VIDEO
|
|
||||||
#define HAVE_PYGAME_SDL_RWOPS
|
|
||||||
|
|
||||||
#include "pgcompat.h"
|
|
||||||
#include "pgplatform.h"
|
|
||||||
#include <Python.h>
|
|
||||||
|
|
||||||
#include <ft2build.h>
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
#include FT_CACHE_H
|
|
||||||
#include FT_XFREE86_H
|
|
||||||
#include FT_TRIGONOMETRY_H
|
|
||||||
|
|
||||||
/**********************************************************
|
|
||||||
* Global module constants
|
|
||||||
**********************************************************/
|
|
||||||
|
|
||||||
/* Render styles */
|
|
||||||
#define FT_STYLE_NORMAL 0x00
|
|
||||||
#define FT_STYLE_STRONG 0x01
|
|
||||||
#define FT_STYLE_OBLIQUE 0x02
|
|
||||||
#define FT_STYLE_UNDERLINE 0x04
|
|
||||||
#define FT_STYLE_WIDE 0x08
|
|
||||||
#define FT_STYLE_DEFAULT 0xFF
|
|
||||||
|
|
||||||
/* Bounding box modes */
|
|
||||||
#define FT_BBOX_EXACT FT_GLYPH_BBOX_SUBPIXELS
|
|
||||||
#define FT_BBOX_EXACT_GRIDFIT FT_GLYPH_BBOX_GRIDFIT
|
|
||||||
#define FT_BBOX_PIXEL FT_GLYPH_BBOX_TRUNCATE
|
|
||||||
#define FT_BBOX_PIXEL_GRIDFIT FT_GLYPH_BBOX_PIXELS
|
|
||||||
|
|
||||||
/* Rendering flags */
|
|
||||||
#define FT_RFLAG_NONE (0)
|
|
||||||
#define FT_RFLAG_ANTIALIAS (1 << 0)
|
|
||||||
#define FT_RFLAG_AUTOHINT (1 << 1)
|
|
||||||
#define FT_RFLAG_VERTICAL (1 << 2)
|
|
||||||
#define FT_RFLAG_HINTED (1 << 3)
|
|
||||||
#define FT_RFLAG_KERNING (1 << 4)
|
|
||||||
#define FT_RFLAG_TRANSFORM (1 << 5)
|
|
||||||
#define FT_RFLAG_PAD (1 << 6)
|
|
||||||
#define FT_RFLAG_ORIGIN (1 << 7)
|
|
||||||
#define FT_RFLAG_UCS4 (1 << 8)
|
|
||||||
#define FT_RFLAG_USE_BITMAP_STRIKES (1 << 9)
|
|
||||||
#define FT_RFLAG_DEFAULTS (FT_RFLAG_HINTED | \
|
|
||||||
FT_RFLAG_USE_BITMAP_STRIKES | \
|
|
||||||
FT_RFLAG_ANTIALIAS)
|
|
||||||
|
|
||||||
|
|
||||||
#define FT_RENDER_NEWBYTEARRAY 0x0
|
|
||||||
#define FT_RENDER_NEWSURFACE 0x1
|
|
||||||
#define FT_RENDER_EXISTINGSURFACE 0x2
|
|
||||||
|
|
||||||
/**********************************************************
|
|
||||||
* Global module types
|
|
||||||
**********************************************************/
|
|
||||||
|
|
||||||
typedef struct _scale_s {
|
|
||||||
FT_UInt x, y;
|
|
||||||
} Scale_t;
|
|
||||||
typedef FT_Angle Angle_t;
|
|
||||||
|
|
||||||
struct fontinternals_;
|
|
||||||
struct freetypeinstance_;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FT_Long font_index;
|
|
||||||
FT_Open_Args open_args;
|
|
||||||
} pgFontId;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
pgFontId id;
|
|
||||||
PyObject *path;
|
|
||||||
int is_scalable;
|
|
||||||
|
|
||||||
Scale_t face_size;
|
|
||||||
FT_Int16 style;
|
|
||||||
FT_Int16 render_flags;
|
|
||||||
double strength;
|
|
||||||
double underline_adjustment;
|
|
||||||
FT_UInt resolution;
|
|
||||||
Angle_t rotation;
|
|
||||||
FT_Matrix transform;
|
|
||||||
FT_Byte fgcolor[4];
|
|
||||||
|
|
||||||
struct freetypeinstance_ *freetype; /* Personal reference */
|
|
||||||
struct fontinternals_ *_internals;
|
|
||||||
} pgFontObject;
|
|
||||||
|
|
||||||
#define pgFont_IS_ALIVE(o) \
|
|
||||||
(((pgFontObject *)(o))->_internals != 0)
|
|
||||||
|
|
||||||
/* import public API */
|
|
||||||
#include "include/pygame_freetype.h"
|
|
||||||
|
|
||||||
#define PYGAMEAPI_FREETYPE_NUMSLOTS 2
|
|
||||||
|
|
||||||
#endif /* ~_PYGAME_FREETYPE_INTERNAL_H_ */
|
|
||||||
|
|
@ -1,632 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PYGAME_H
|
|
||||||
#define _PYGAME_H
|
|
||||||
|
|
||||||
/** This header file includes all the definitions for the
|
|
||||||
** base pygame extensions. This header only requires
|
|
||||||
** Python includes (and SDL.h for functions that use SDL types).
|
|
||||||
** The reason for functions prototyped with #define's is
|
|
||||||
** to allow for maximum Python portability. It also uses
|
|
||||||
** Python as the runtime linker, which allows for late binding.
|
|
||||||
'' For more information on this style of development, read
|
|
||||||
** the Python docs on this subject.
|
|
||||||
** http://www.python.org/doc/current/ext/using-cobjects.html
|
|
||||||
**
|
|
||||||
** If using this to build your own derived extensions,
|
|
||||||
** you'll see that the functions available here are mainly
|
|
||||||
** used to help convert between python objects and SDL objects.
|
|
||||||
** Since this library doesn't add a lot of functionality to
|
|
||||||
** the SDL library, it doesn't need to offer a lot either.
|
|
||||||
**
|
|
||||||
** When initializing your extension module, you must manually
|
|
||||||
** import the modules you want to use. (this is the part about
|
|
||||||
** using python as the runtime linker). Each module has its
|
|
||||||
** own import_xxx() routine. You need to perform this import
|
|
||||||
** after you have initialized your own module, and before
|
|
||||||
** you call any routines from that module. Since every module
|
|
||||||
** in pygame does this, there are plenty of examples.
|
|
||||||
**
|
|
||||||
** The base module does include some useful conversion routines
|
|
||||||
** that you are free to use in your own extension.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "pgplatform.h"
|
|
||||||
#include <Python.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* version macros (defined since version 1.9.5) */
|
|
||||||
#define PG_MAJOR_VERSION 2
|
|
||||||
#define PG_MINOR_VERSION 0
|
|
||||||
#define PG_PATCH_VERSION 0
|
|
||||||
#define PG_VERSIONNUM(MAJOR, MINOR, PATCH) (1000*(MAJOR) + 100*(MINOR) + (PATCH))
|
|
||||||
#define PG_VERSION_ATLEAST(MAJOR, MINOR, PATCH) \
|
|
||||||
(PG_VERSIONNUM(PG_MAJOR_VERSION, PG_MINOR_VERSION, PG_PATCH_VERSION) >= \
|
|
||||||
PG_VERSIONNUM(MAJOR, MINOR, PATCH))
|
|
||||||
|
|
||||||
/* SDL 1.x/2.x and pygame 1.x/2.x
|
|
||||||
*/
|
|
||||||
#if defined(SDL_VERSION_ATLEAST)
|
|
||||||
#if (SDL_VERSION_ATLEAST(2, 0, 0))
|
|
||||||
#define PG_API_VERSION 2
|
|
||||||
#else /* SDL 1 */
|
|
||||||
/* for now: allow pygame 2 to be compiled with SDL 1. */
|
|
||||||
#define PG_API_VERSION 1
|
|
||||||
#endif /* SDL 1 */
|
|
||||||
#else /* NO SDL */
|
|
||||||
#define PG_API_VERSION ((PG_MAJOR_VERSION == 1) ? 1 : 2)
|
|
||||||
#endif /* NO SDL */
|
|
||||||
|
|
||||||
#include "pgcompat.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Flag indicating a pg_buffer; used for assertions within callbacks */
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define PyBUF_PYGAME 0x4000
|
|
||||||
#endif
|
|
||||||
#define PyBUF_HAS_FLAG(f, F) (((f) & (F)) == (F))
|
|
||||||
|
|
||||||
/* Array information exchange struct C type; inherits from Py_buffer
|
|
||||||
*
|
|
||||||
* Pygame uses its own Py_buffer derived C struct as an internal representation
|
|
||||||
* of an imported array buffer. The extended Py_buffer allows for a
|
|
||||||
* per-instance release callback,
|
|
||||||
*/
|
|
||||||
typedef void (*pybuffer_releaseproc)(Py_buffer *);
|
|
||||||
|
|
||||||
typedef struct pg_bufferinfo_s {
|
|
||||||
Py_buffer view;
|
|
||||||
PyObject *consumer; /* Input: Borrowed reference */
|
|
||||||
pybuffer_releaseproc release_buffer;
|
|
||||||
} pg_buffer;
|
|
||||||
|
|
||||||
#include "pgimport.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BASE module
|
|
||||||
*/
|
|
||||||
#ifndef PYGAMEAPI_BASE_INTERNAL
|
|
||||||
#define pgExc_SDLError \
|
|
||||||
((PyObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 0))
|
|
||||||
|
|
||||||
#define pg_RegisterQuit \
|
|
||||||
(*(void (*)(void (*)(void))) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 1))
|
|
||||||
|
|
||||||
#define pg_IntFromObj \
|
|
||||||
(*(int (*)(PyObject *, int *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 2))
|
|
||||||
|
|
||||||
#define pg_IntFromObjIndex \
|
|
||||||
(*(int (*)(PyObject *, int, int *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 3))
|
|
||||||
|
|
||||||
#define pg_TwoIntsFromObj \
|
|
||||||
(*(int (*)(PyObject *, int *, int *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 4))
|
|
||||||
|
|
||||||
#define pg_FloatFromObj \
|
|
||||||
(*(int (*)(PyObject *, float *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 5))
|
|
||||||
|
|
||||||
#define pg_FloatFromObjIndex \
|
|
||||||
(*(int (*)(PyObject *, int, float *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 6))
|
|
||||||
|
|
||||||
#define pg_TwoFloatsFromObj \
|
|
||||||
(*(int (*)(PyObject *, float *, float *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 7))
|
|
||||||
|
|
||||||
#define pg_UintFromObj \
|
|
||||||
(*(int (*)(PyObject *, Uint32 *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 8))
|
|
||||||
|
|
||||||
#define pg_UintFromObjIndex \
|
|
||||||
(*(int (*)(PyObject *, int, Uint32 *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 9))
|
|
||||||
|
|
||||||
#define pgVideo_AutoQuit \
|
|
||||||
(*(void (*)(void)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 10))
|
|
||||||
|
|
||||||
#define pgVideo_AutoInit \
|
|
||||||
(*(int (*)(void)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 11))
|
|
||||||
|
|
||||||
#define pg_RGBAFromObj \
|
|
||||||
(*(int (*)(PyObject *, Uint8 *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 12))
|
|
||||||
|
|
||||||
#define pgBuffer_AsArrayInterface \
|
|
||||||
(*(PyObject * (*)(Py_buffer *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 13))
|
|
||||||
|
|
||||||
#define pgBuffer_AsArrayStruct \
|
|
||||||
(*(PyObject * (*)(Py_buffer *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 14))
|
|
||||||
|
|
||||||
#define pgObject_GetBuffer \
|
|
||||||
(*(int (*)(PyObject *, pg_buffer *, int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 15))
|
|
||||||
|
|
||||||
#define pgBuffer_Release \
|
|
||||||
(*(void (*)(pg_buffer *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 16))
|
|
||||||
|
|
||||||
#define pgDict_AsBuffer \
|
|
||||||
(*(int (*)(pg_buffer *, PyObject *, int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 17))
|
|
||||||
|
|
||||||
#define pgExc_BufferError \
|
|
||||||
((PyObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 18))
|
|
||||||
|
|
||||||
#if PG_API_VERSION == 2
|
|
||||||
#define pg_GetDefaultWindow \
|
|
||||||
(*(SDL_Window * (*)(void)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 19))
|
|
||||||
|
|
||||||
#define pg_SetDefaultWindow \
|
|
||||||
(*(void (*)(SDL_Window *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 20))
|
|
||||||
|
|
||||||
#define pg_GetDefaultWindowSurface \
|
|
||||||
(*(PyObject * (*)(void)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 21))
|
|
||||||
|
|
||||||
#define pg_SetDefaultWindowSurface \
|
|
||||||
(*(void (*)(PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(base, 22))
|
|
||||||
|
|
||||||
#endif /* PG_API_VERSION == 2 */
|
|
||||||
|
|
||||||
#define import_pygame_base() IMPORT_PYGAME_MODULE(base)
|
|
||||||
#endif /* ~PYGAMEAPI_BASE_INTERNAL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RECT module
|
|
||||||
*/
|
|
||||||
#if !defined(SDL_VERSION_ATLEAST) || PG_API_VERSION == 1
|
|
||||||
typedef struct {
|
|
||||||
int x, y;
|
|
||||||
int w, h;
|
|
||||||
} GAME_Rect;
|
|
||||||
#else /* SDL 2+ */
|
|
||||||
typedef SDL_Rect GAME_Rect;
|
|
||||||
#endif /* SDL 2+ */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD GAME_Rect r;
|
|
||||||
PyObject *weakreflist;
|
|
||||||
} pgRectObject;
|
|
||||||
|
|
||||||
#define pgRect_AsRect(x) (((pgRectObject *)x)->r)
|
|
||||||
#ifndef PYGAMEAPI_RECT_INTERNAL
|
|
||||||
#define pgRect_Type \
|
|
||||||
(*(PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rect, 0))
|
|
||||||
|
|
||||||
#define pgRect_Check(x) \
|
|
||||||
((x)->ob_type == &pgRect_Type)
|
|
||||||
#define pgRect_New \
|
|
||||||
(*(PyObject * (*)(SDL_Rect *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rect, 1))
|
|
||||||
|
|
||||||
#define pgRect_New4 \
|
|
||||||
(*(PyObject * (*)(int, int, int, int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rect, 2))
|
|
||||||
|
|
||||||
#define pgRect_FromObject \
|
|
||||||
(*(GAME_Rect * (*)(PyObject *, GAME_Rect *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rect, 3))
|
|
||||||
|
|
||||||
#define import_pygame_rect() IMPORT_PYGAME_MODULE(rect)
|
|
||||||
#endif /* ~PYGAMEAPI_RECT_INTERNAL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CDROM module
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD int id;
|
|
||||||
} pgCDObject;
|
|
||||||
|
|
||||||
#define pgCD_AsID(x) (((pgCDObject *)x)->id)
|
|
||||||
#ifndef PYGAMEAPI_CDROM_INTERNAL
|
|
||||||
#define pgCD_Type \
|
|
||||||
(*(PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(cdrom, 0))
|
|
||||||
|
|
||||||
#define pgCD_Check(x) \
|
|
||||||
((x)->ob_type == &pgCD_Type)
|
|
||||||
#define pgCD_New \
|
|
||||||
(*(PyObject * (*)(int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(cdrom, 1))
|
|
||||||
|
|
||||||
#define import_pygame_cd() IMPORT_PYGAME_MODULE(cdrom)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* JOYSTICK module
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD int id;
|
|
||||||
} pgJoystickObject;
|
|
||||||
|
|
||||||
#define pgJoystick_AsID(x) (((pgJoystickObject *)x)->id)
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_JOYSTICK_INTERNAL
|
|
||||||
#define pgJoystick_Type \
|
|
||||||
(*(PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(joystick, 0))
|
|
||||||
|
|
||||||
#define pgJoystick_Check(x) \
|
|
||||||
((x)->ob_type == &pgJoystick_Type)
|
|
||||||
#define pgJoystick_New \
|
|
||||||
(*(PyObject * (*)(int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(joystick, 1))
|
|
||||||
|
|
||||||
#define import_pygame_joystick() IMPORT_PYGAME_MODULE(joystick)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DISPLAY module
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(SDL_VERSION_ATLEAST)
|
|
||||||
|
|
||||||
#if PG_API_VERSION == 2
|
|
||||||
typedef struct {
|
|
||||||
Uint32 hw_available:1;
|
|
||||||
Uint32 wm_available:1;
|
|
||||||
Uint32 blit_hw:1;
|
|
||||||
Uint32 blit_hw_CC:1;
|
|
||||||
Uint32 blit_hw_A:1;
|
|
||||||
Uint32 blit_sw:1;
|
|
||||||
Uint32 blit_sw_CC:1;
|
|
||||||
Uint32 blit_sw_A:1;
|
|
||||||
Uint32 blit_fill:1;
|
|
||||||
Uint32 video_mem;
|
|
||||||
SDL_PixelFormat *vfmt;
|
|
||||||
SDL_PixelFormat vfmt_data;
|
|
||||||
int current_w;
|
|
||||||
int current_h;
|
|
||||||
} pg_VideoInfo;
|
|
||||||
#endif /* PG_API_VERSION == 2 */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
#if PG_API_VERSION == 1
|
|
||||||
PyObject_HEAD SDL_VideoInfo info;
|
|
||||||
#else
|
|
||||||
PyObject_HEAD pg_VideoInfo info;
|
|
||||||
#endif
|
|
||||||
} pgVidInfoObject;
|
|
||||||
|
|
||||||
#define pgVidInfo_AsVidInfo(x) (((pgVidInfoObject *)x)->info)
|
|
||||||
#endif /* defined(SDL_VERSION_ATLEAST) */
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_DISPLAY_INTERNAL
|
|
||||||
#define pgVidInfo_Type \
|
|
||||||
(*(PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(display, 0))
|
|
||||||
|
|
||||||
#define pgVidInfo_Check(x) \
|
|
||||||
((x)->ob_type == &pgVidInfo_Type)
|
|
||||||
|
|
||||||
#if PG_API_VERSION == 1
|
|
||||||
#define pgVidInfo_New \
|
|
||||||
(*(PyObject * (*)(SDL_VideoInfo *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(display, 1))
|
|
||||||
#else
|
|
||||||
#define pgVidInfo_New \
|
|
||||||
(*(PyObject * (*)(pg_VideoInfo *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(display, 1))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define import_pygame_display() IMPORT_PYGAME_MODULE(display)
|
|
||||||
#endif /* ~PYGAMEAPI_DISPLAY_INTERNAL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SURFACE module
|
|
||||||
*/
|
|
||||||
struct pgSubSurface_Data;
|
|
||||||
struct SDL_Surface;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD struct SDL_Surface *surf;
|
|
||||||
#if PG_API_VERSION == 2
|
|
||||||
int owner;
|
|
||||||
#endif /* PG_API_VERSION == 2 */
|
|
||||||
struct pgSubSurface_Data *subsurface; /* ptr to subsurface data (if a
|
|
||||||
* subsurface)*/
|
|
||||||
PyObject *weakreflist;
|
|
||||||
PyObject *locklist;
|
|
||||||
PyObject *dependency;
|
|
||||||
} pgSurfaceObject;
|
|
||||||
#define pgSurface_AsSurface(x) (((pgSurfaceObject *)x)->surf)
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_SURFACE_INTERNAL
|
|
||||||
#define pgSurface_Type \
|
|
||||||
(*(PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surface, 0))
|
|
||||||
|
|
||||||
#define pgSurface_Check(x) \
|
|
||||||
(PyObject_IsInstance((x), (PyObject *) &pgSurface_Type))
|
|
||||||
#if PG_API_VERSION == 1
|
|
||||||
#define pgSurface_New \
|
|
||||||
(*(PyObject * (*)(SDL_Surface *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surface, 1))
|
|
||||||
|
|
||||||
#define pgSurface_SetSurface \
|
|
||||||
(*(int (*)(PyObject *, SDL_Surface *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surface, 3))
|
|
||||||
|
|
||||||
#else /* PG_API_VERSION == 2 */
|
|
||||||
#define pgSurface_New2 \
|
|
||||||
(*(PyObject * (*)(SDL_Surface *, int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surface, 1))
|
|
||||||
|
|
||||||
#define pgSurface_SetSurface \
|
|
||||||
(*(int (*)(PyObject *, SDL_Surface *, int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surface, 3))
|
|
||||||
|
|
||||||
#endif /* PG_API_VERSION == 2 */
|
|
||||||
#define pgSurface_Blit \
|
|
||||||
(*(int (*)(PyObject *, PyObject *, GAME_Rect *, GAME_Rect *, int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surface, 2))
|
|
||||||
|
|
||||||
#define import_pygame_surface() \
|
|
||||||
do { \
|
|
||||||
IMPORT_PYGAME_MODULE(surface); \
|
|
||||||
if (PyErr_Occurred() != NULL) \
|
|
||||||
break; \
|
|
||||||
IMPORT_PYGAME_MODULE(surflock); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#if PG_API_VERSION == 2
|
|
||||||
#define pgSurface_New(surface) pgSurface_New2((surface), 1)
|
|
||||||
#define pgSurface_NewNoOwn(surface) pgSurface_New2((surface), 0)
|
|
||||||
#endif /* PG_API_VERSION == 2 */
|
|
||||||
|
|
||||||
#endif /* ~PYGAMEAPI_SURFACE_INTERNAL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SURFLOCK module
|
|
||||||
* auto imported/initialized by surface
|
|
||||||
*/
|
|
||||||
#ifndef PYGAMEAPI_SURFLOCK_INTERNAL
|
|
||||||
#define pgLifetimeLock_Type \
|
|
||||||
(*(PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 0))
|
|
||||||
|
|
||||||
#define pgLifetimeLock_Check(x) \
|
|
||||||
((x)->ob_type == &pgLifetimeLock_Type)
|
|
||||||
|
|
||||||
#define pgSurface_Prep(x) \
|
|
||||||
if (((pgSurfaceObject *)x)->subsurface) \
|
|
||||||
(*(*(void (*)(PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 1)))(x)
|
|
||||||
|
|
||||||
#define pgSurface_Unprep(x) \
|
|
||||||
if (((pgSurfaceObject *)x)->subsurface) \
|
|
||||||
(*(*(void (*)(PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 2)))(x)
|
|
||||||
|
|
||||||
#define pgSurface_Lock \
|
|
||||||
(*(int (*)(PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 3))
|
|
||||||
|
|
||||||
#define pgSurface_Unlock \
|
|
||||||
(*(int (*)(PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 4))
|
|
||||||
|
|
||||||
#define pgSurface_LockBy \
|
|
||||||
(*(int (*)(PyObject *, PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 5))
|
|
||||||
|
|
||||||
#define pgSurface_UnlockBy \
|
|
||||||
(*(int (*)(PyObject *, PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 6))
|
|
||||||
|
|
||||||
#define pgSurface_LockLifetime \
|
|
||||||
(*(PyObject * (*)(PyObject *, PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(surflock, 7))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* EVENT module
|
|
||||||
*/
|
|
||||||
typedef struct pgEventObject pgEventObject;
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_EVENT_INTERNAL
|
|
||||||
#define pgEvent_Type \
|
|
||||||
(*(PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(event, 0))
|
|
||||||
|
|
||||||
#define pgEvent_Check(x) \
|
|
||||||
((x)->ob_type == &pgEvent_Type)
|
|
||||||
|
|
||||||
#define pgEvent_New \
|
|
||||||
(*(PyObject * (*)(SDL_Event *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(event, 1))
|
|
||||||
|
|
||||||
#define pgEvent_New2 \
|
|
||||||
(*(PyObject * (*)(int, PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(event, 2))
|
|
||||||
|
|
||||||
#define pgEvent_FillUserEvent \
|
|
||||||
(*(int (*)(pgEventObject *, SDL_Event *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(event, 3))
|
|
||||||
|
|
||||||
#if PG_API_VERSION == 2
|
|
||||||
#define pg_EnableKeyRepeat \
|
|
||||||
(*(int (*)(int, int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(event, 4))
|
|
||||||
|
|
||||||
#define pg_GetKeyRepeat \
|
|
||||||
(*(void (*)(int *, int *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(event, 5))
|
|
||||||
#endif /* PG_API_VERSION == 2 */
|
|
||||||
|
|
||||||
#define import_pygame_event() IMPORT_PYGAME_MODULE(event)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RWOBJECT module
|
|
||||||
* the rwobject are only needed for C side work, not accessable from python.
|
|
||||||
*/
|
|
||||||
#ifndef PYGAMEAPI_RWOBJECT_INTERNAL
|
|
||||||
#define pgRWops_FromObject \
|
|
||||||
(*(SDL_RWops * (*)(PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rwobject, 0))
|
|
||||||
|
|
||||||
#define pgRWops_IsFileObject \
|
|
||||||
(*(int (*)(SDL_RWops *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rwobject, 1))
|
|
||||||
|
|
||||||
#define pg_EncodeFilePath \
|
|
||||||
(*(PyObject * (*)(PyObject *, PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rwobject, 2))
|
|
||||||
|
|
||||||
#define pg_EncodeString \
|
|
||||||
(*(PyObject * (*)(PyObject *, const char *, const char *, PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rwobject, 3))
|
|
||||||
|
|
||||||
#define pgRWops_FromFileObject \
|
|
||||||
(*(SDL_RWops * (*)(PyObject *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rwobject, 4))
|
|
||||||
|
|
||||||
#define pgRWops_ReleaseObject \
|
|
||||||
(*(int (*)(SDL_RWops *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(rwobject, 5))
|
|
||||||
|
|
||||||
#define import_pygame_rwobject() IMPORT_PYGAME_MODULE(rwobject)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PixelArray module
|
|
||||||
*/
|
|
||||||
#ifndef PYGAMEAPI_PIXELARRAY_INTERNAL
|
|
||||||
#define PyPixelArray_Type \
|
|
||||||
((PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(pixelarray, 0))
|
|
||||||
|
|
||||||
#define PyPixelArray_Check(x) \
|
|
||||||
((x)->ob_type == &PyPixelArray_Type)
|
|
||||||
#define PyPixelArray_New \
|
|
||||||
(*(PyObject * (*)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(pixelarray, 1))
|
|
||||||
|
|
||||||
#define import_pygame_pixelarray() IMPORT_PYGAME_MODULE(pixelarray)
|
|
||||||
#endif /* PYGAMEAPI_PIXELARRAY_INTERNAL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Color module
|
|
||||||
*/
|
|
||||||
typedef struct pgColorObject pgColorObject;
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_COLOR_INTERNAL
|
|
||||||
#define pgColor_Type (*(PyObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(color, 0))
|
|
||||||
|
|
||||||
#define pgColor_Check(x) \
|
|
||||||
((x)->ob_type == &pgColor_Type)
|
|
||||||
#define pgColor_New \
|
|
||||||
(*(PyObject * (*)(Uint8 *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(color, 1))
|
|
||||||
|
|
||||||
#define pgColor_NewLength \
|
|
||||||
(*(PyObject * (*)(Uint8 *, Uint8)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(color, 3))
|
|
||||||
|
|
||||||
#define pg_RGBAFromColorObj \
|
|
||||||
(*(int (*)(PyObject *, Uint8 *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(color, 2))
|
|
||||||
|
|
||||||
#define pg_RGBAFromFuzzyColorObj \
|
|
||||||
(*(int (*)(PyObject *, Uint8 *)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(color, 4))
|
|
||||||
|
|
||||||
#define pgColor_AsArray(x) (((pgColorObject *)x)->data)
|
|
||||||
#define pgColor_NumComponents(x) (((pgColorObject *)x)->len)
|
|
||||||
|
|
||||||
|
|
||||||
#define import_pygame_color() IMPORT_PYGAME_MODULE(color)
|
|
||||||
#endif /* PYGAMEAPI_COLOR_INTERNAL */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Math module
|
|
||||||
*/
|
|
||||||
#ifndef PYGAMEAPI_MATH_INTERNAL
|
|
||||||
#define pgVector2_Check(x) \
|
|
||||||
((x)->ob_type == (PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(math, 0))
|
|
||||||
|
|
||||||
#define pgVector3_Check(x) \
|
|
||||||
((x)->ob_type == (PyTypeObject *) \
|
|
||||||
PYGAMEAPI_GET_SLOT(math, 1))
|
|
||||||
/*
|
|
||||||
#define pgVector2_New \
|
|
||||||
(*(PyObject*(*)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(PyGAME_C_API, 1))
|
|
||||||
*/
|
|
||||||
#define import_pygame_math() IMPORT_PYGAME_MODULE(math)
|
|
||||||
#endif /* PYGAMEAPI_MATH_INTERNAL */
|
|
||||||
|
|
||||||
#define IMPORT_PYGAME_MODULE _IMPORT_PYGAME_MODULE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* base pygame API slots
|
|
||||||
* disable slots with NO_PYGAME_C_API
|
|
||||||
*/
|
|
||||||
#ifdef PYGAME_H
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(base);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(rect);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(cdrom);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(joystick);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(display);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(surface);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(surflock);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(event);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(rwobject);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(pixelarray);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(color);
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(math);
|
|
||||||
#else /* ~PYGAME_H */
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(base);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(rect);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(cdrom);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(joystick);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(display);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(surface);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(surflock);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(event);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(rwobject);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(pixelarray);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(color);
|
|
||||||
PYGAMEAPI_EXTERN_SLOTS(math);
|
|
||||||
#endif /* ~PYGAME_H */
|
|
||||||
|
|
||||||
#endif /* PYGAME_H */
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
/*
|
|
||||||
Bitmask 1.7 - A pixel-perfect collision detection library.
|
|
||||||
|
|
||||||
Copyright (C) 2002-2005 Ulf Ekstrom except for the bitcount
|
|
||||||
function which is copyright (C) Donald W. Gillies, 1992.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef BITMASK_H
|
|
||||||
#define BITMASK_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
/* Define INLINE for different compilers. If your compiler does not
|
|
||||||
support inlining then there might be a performance hit in
|
|
||||||
bitmask_overlap_area().
|
|
||||||
*/
|
|
||||||
#ifndef INLINE
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define INLINE inline
|
|
||||||
# else
|
|
||||||
# ifdef _MSC_VER
|
|
||||||
# define INLINE __inline
|
|
||||||
# else
|
|
||||||
# define INLINE
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BITMASK_W unsigned long int
|
|
||||||
#define BITMASK_W_LEN (sizeof(BITMASK_W)*CHAR_BIT)
|
|
||||||
#define BITMASK_W_MASK (BITMASK_W_LEN - 1)
|
|
||||||
#define BITMASK_N(n) ((BITMASK_W)1 << (n))
|
|
||||||
|
|
||||||
typedef struct bitmask
|
|
||||||
{
|
|
||||||
int w,h;
|
|
||||||
BITMASK_W bits[1];
|
|
||||||
} bitmask_t;
|
|
||||||
|
|
||||||
/* Creates a bitmask of width w and height h, where
|
|
||||||
w and h must both be greater than or equal to 0.
|
|
||||||
The mask is automatically cleared when created.
|
|
||||||
*/
|
|
||||||
bitmask_t *bitmask_create(int w, int h);
|
|
||||||
|
|
||||||
/* Frees all the memory allocated by bitmask_create for m. */
|
|
||||||
void bitmask_free(bitmask_t *m);
|
|
||||||
|
|
||||||
/* Create a copy of the given bitmask. */
|
|
||||||
bitmask_t *bitmask_copy(bitmask_t *m);
|
|
||||||
|
|
||||||
/* Clears all bits in the mask */
|
|
||||||
void bitmask_clear(bitmask_t *m);
|
|
||||||
|
|
||||||
/* Sets all bits in the mask */
|
|
||||||
void bitmask_fill(bitmask_t *m);
|
|
||||||
|
|
||||||
/* Flips all bits in the mask */
|
|
||||||
void bitmask_invert(bitmask_t *m);
|
|
||||||
|
|
||||||
/* Counts the bits in the mask */
|
|
||||||
unsigned int bitmask_count(bitmask_t *m);
|
|
||||||
|
|
||||||
/* Returns nonzero if the bit at (x,y) is set. Coordinates start at
|
|
||||||
(0,0) */
|
|
||||||
static INLINE int bitmask_getbit(const bitmask_t *m, int x, int y)
|
|
||||||
{
|
|
||||||
return (m->bits[x/BITMASK_W_LEN*m->h + y] & BITMASK_N(x & BITMASK_W_MASK)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets the bit at (x,y) */
|
|
||||||
static INLINE void bitmask_setbit(bitmask_t *m, int x, int y)
|
|
||||||
{
|
|
||||||
m->bits[x/BITMASK_W_LEN*m->h + y] |= BITMASK_N(x & BITMASK_W_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clears the bit at (x,y) */
|
|
||||||
static INLINE void bitmask_clearbit(bitmask_t *m, int x, int y)
|
|
||||||
{
|
|
||||||
m->bits[x/BITMASK_W_LEN*m->h + y] &= ~BITMASK_N(x & BITMASK_W_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns nonzero if the masks overlap with the given offset.
|
|
||||||
The overlap tests uses the following offsets (which may be negative):
|
|
||||||
|
|
||||||
+----+----------..
|
|
||||||
|A | yoffset
|
|
||||||
| +-+----------..
|
|
||||||
+--|B
|
|
||||||
|xoffset
|
|
||||||
| |
|
|
||||||
: :
|
|
||||||
*/
|
|
||||||
int bitmask_overlap(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
|
|
||||||
|
|
||||||
/* Like bitmask_overlap(), but will also give a point of intersection.
|
|
||||||
x and y are given in the coordinates of mask a, and are untouched
|
|
||||||
if there is no overlap. */
|
|
||||||
int bitmask_overlap_pos(const bitmask_t *a, const bitmask_t *b,
|
|
||||||
int xoffset, int yoffset, int *x, int *y);
|
|
||||||
|
|
||||||
/* Returns the number of overlapping 'pixels' */
|
|
||||||
int bitmask_overlap_area(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
|
|
||||||
|
|
||||||
/* Fills a mask with the overlap of two other masks. A bitwise AND. */
|
|
||||||
void bitmask_overlap_mask (const bitmask_t *a, const bitmask_t *b, bitmask_t *c, int xoffset, int yoffset);
|
|
||||||
|
|
||||||
/* Draws mask b onto mask a (bitwise OR). Can be used to compose large
|
|
||||||
(game background?) mask from several submasks, which may speed up
|
|
||||||
the testing. */
|
|
||||||
|
|
||||||
void bitmask_draw(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
|
|
||||||
|
|
||||||
void bitmask_erase(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset);
|
|
||||||
|
|
||||||
/* Return a new scaled bitmask, with dimensions w*h. The quality of the
|
|
||||||
scaling may not be perfect for all circumstances, but it should
|
|
||||||
be reasonable. If either w or h is 0 a clear 1x1 mask is returned. */
|
|
||||||
bitmask_t *bitmask_scale(const bitmask_t *m, int w, int h);
|
|
||||||
|
|
||||||
/* Convolve b into a, drawing the output into o, shifted by offset. If offset
|
|
||||||
* is 0, then the (x,y) bit will be set if and only if
|
|
||||||
* bitmask_overlap(a, b, x - b->w - 1, y - b->h - 1) returns true.
|
|
||||||
*
|
|
||||||
* Modifies bits o[xoffset ... xoffset + a->w + b->w - 1)
|
|
||||||
* [yoffset ... yoffset + a->h + b->h - 1). */
|
|
||||||
void bitmask_convolve(const bitmask_t *a, const bitmask_t *b, bitmask_t *o, int xoffset, int yoffset);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* End of extern "C" { */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,180 +0,0 @@
|
||||||
/* Python 2.x/3.x and SDL compatibility tools
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(PGCOMPAT_H)
|
|
||||||
#define PGCOMPAT_H
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
|
|
||||||
/* Cobjects vanish in Python 3.2; so we will code as though we use capsules */
|
|
||||||
#if defined(Py_CAPSULE_H)
|
|
||||||
#define PG_HAVE_CAPSULE 1
|
|
||||||
#else
|
|
||||||
#define PG_HAVE_CAPSULE 0
|
|
||||||
#endif
|
|
||||||
#if defined(Py_COBJECT_H)
|
|
||||||
#define PG_HAVE_COBJECT 1
|
|
||||||
#else
|
|
||||||
#define PG_HAVE_COBJECT 0
|
|
||||||
#endif
|
|
||||||
#if !PG_HAVE_CAPSULE
|
|
||||||
#define PyCapsule_New(ptr, n, dfn) PyCObject_FromVoidPtr(ptr, dfn)
|
|
||||||
#define PyCapsule_GetPointer(obj, n) PyCObject_AsVoidPtr(obj)
|
|
||||||
#define PyCapsule_CheckExact(obj) PyCObject_Check(obj)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Pygame uses Py_buffer (PEP 3118) to exchange array information internally;
|
|
||||||
* define here as needed.
|
|
||||||
*/
|
|
||||||
#if !defined(PyBUF_SIMPLE)
|
|
||||||
typedef struct bufferinfo {
|
|
||||||
void *buf;
|
|
||||||
PyObject *obj;
|
|
||||||
Py_ssize_t len;
|
|
||||||
Py_ssize_t itemsize;
|
|
||||||
int readonly;
|
|
||||||
int ndim;
|
|
||||||
char *format;
|
|
||||||
Py_ssize_t *shape;
|
|
||||||
Py_ssize_t *strides;
|
|
||||||
Py_ssize_t *suboffsets;
|
|
||||||
void *internal;
|
|
||||||
} Py_buffer;
|
|
||||||
|
|
||||||
/* Flags for getting buffers */
|
|
||||||
#define PyBUF_SIMPLE 0
|
|
||||||
#define PyBUF_WRITABLE 0x0001
|
|
||||||
/* we used to include an E, backwards compatible alias */
|
|
||||||
#define PyBUF_WRITEABLE PyBUF_WRITABLE
|
|
||||||
#define PyBUF_FORMAT 0x0004
|
|
||||||
#define PyBUF_ND 0x0008
|
|
||||||
#define PyBUF_STRIDES (0x0010 | PyBUF_ND)
|
|
||||||
#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
|
|
||||||
#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
|
|
||||||
#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
|
|
||||||
#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
|
|
||||||
|
|
||||||
#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE)
|
|
||||||
#define PyBUF_CONTIG_RO (PyBUF_ND)
|
|
||||||
|
|
||||||
#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE)
|
|
||||||
#define PyBUF_STRIDED_RO (PyBUF_STRIDES)
|
|
||||||
|
|
||||||
#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT)
|
|
||||||
#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT)
|
|
||||||
|
|
||||||
#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT)
|
|
||||||
#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT)
|
|
||||||
|
|
||||||
#define PyBUF_READ 0x100
|
|
||||||
#define PyBUF_WRITE 0x200
|
|
||||||
#define PyBUF_SHADOW 0x400
|
|
||||||
|
|
||||||
typedef int(*getbufferproc)(PyObject *, Py_buffer *, int);
|
|
||||||
typedef void(*releasebufferproc)(Py_buffer *);
|
|
||||||
#endif /* ~defined(PyBUF_SIMPLE) */
|
|
||||||
|
|
||||||
/* define common types where SDL is not included */
|
|
||||||
#ifndef SDL_VERSION_ATLEAST
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
typedef unsigned __int8 uint8_t;
|
|
||||||
typedef unsigned __int32 uint32_t;
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
typedef uint32_t Uint32;
|
|
||||||
typedef uint8_t Uint8;
|
|
||||||
#endif /* no SDL */
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(SDL_VERSION_ATLEAST)
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_VULKAN
|
|
||||||
#define SDL_WINDOW_VULKAN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_ALWAYS_ON_TOP
|
|
||||||
#define SDL_WINDOW_ALWAYS_ON_TOP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_SKIP_TASKBAR
|
|
||||||
#define SDL_WINDOW_SKIP_TASKBAR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_UTILITY
|
|
||||||
#define SDL_WINDOW_UTILITY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_TOOLTIP
|
|
||||||
#define SDL_WINDOW_TOOLTIP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_POPUP_MENU
|
|
||||||
#define SDL_WINDOW_POPUP_MENU 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_INPUT_GRABBED
|
|
||||||
#define SDL_WINDOW_INPUT_GRABBED 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_INPUT_FOCUS
|
|
||||||
#define SDL_WINDOW_INPUT_FOCUS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_MOUSE_FOCUS
|
|
||||||
#define SDL_WINDOW_MOUSE_FOCUS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_FOREIGN
|
|
||||||
#define SDL_WINDOW_FOREIGN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_ALLOW_HIGHDPI
|
|
||||||
#define SDL_WINDOW_ALLOW_HIGHDPI 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_MOUSE_CAPTURE
|
|
||||||
#define SDL_WINDOW_MOUSE_CAPTURE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_ALWAYS_ON_TOP
|
|
||||||
#define SDL_WINDOW_ALWAYS_ON_TOP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_SKIP_TASKBAR
|
|
||||||
#define SDL_WINDOW_SKIP_TASKBAR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_UTILITY
|
|
||||||
#define SDL_WINDOW_UTILITY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_TOOLTIP
|
|
||||||
#define SDL_WINDOW_TOOLTIP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_WINDOW_POPUP_MENU
|
|
||||||
#define SDL_WINDOW_POPUP_MENU 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
|
||||||
/* To control the use of:
|
|
||||||
* SDL_AUDIODEVICEADDED
|
|
||||||
* SDL_AUDIODEVICEREMOVED
|
|
||||||
*
|
|
||||||
* Ref: https://wiki.libsdl.org/SDL_EventType
|
|
||||||
* Ref: https://wiki.libsdl.org/SDL_AudioDeviceEvent
|
|
||||||
*/
|
|
||||||
#define SDL2_AUDIODEVICE_SUPPORTED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SDL_MOUSEWHEEL_FLIPPED
|
|
||||||
#define NO_SDL_MOUSEWHEEL_FLIPPED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* defined(SDL_VERSION_ATLEAST) */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ~defined(PGCOMPAT_H) */
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
#ifndef PGIMPORT_H
|
|
||||||
#define PGIMPORT_H
|
|
||||||
|
|
||||||
/* Prefix when initializing module */
|
|
||||||
#define MODPREFIX ""
|
|
||||||
/* Prefix when importing module */
|
|
||||||
#define IMPPREFIX "pygame."
|
|
||||||
|
|
||||||
#ifdef __SYMBIAN32__
|
|
||||||
|
|
||||||
/* On Symbian there is no pygame package. The extensions are built-in or in
|
|
||||||
* sys\bin. */
|
|
||||||
#undef MODPREFIX
|
|
||||||
#undef IMPPREFIX
|
|
||||||
#define MODPREFIX "pygame_"
|
|
||||||
#define IMPPREFIX "pygame_"
|
|
||||||
|
|
||||||
#endif /* __SYMBIAN32__ */
|
|
||||||
|
|
||||||
#include "pgcompat.h"
|
|
||||||
|
|
||||||
#define PYGAMEAPI_LOCAL_ENTRY "_PYGAME_C_API"
|
|
||||||
#define PG_CAPSULE_NAME(m) (IMPPREFIX m "." PYGAMEAPI_LOCAL_ENTRY)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fill API slots defined by PYGAMEAPI_DEFINE_SLOTS/PYGAMEAPI_EXTERN_SLOTS
|
|
||||||
*/
|
|
||||||
#define _IMPORT_PYGAME_MODULE(module) \
|
|
||||||
{ \
|
|
||||||
PyObject *_module = PyImport_ImportModule(IMPPREFIX #module); \
|
|
||||||
\
|
|
||||||
if (_module != NULL) { \
|
|
||||||
PyObject *_c_api = \
|
|
||||||
PyObject_GetAttrString(_module, PYGAMEAPI_LOCAL_ENTRY); \
|
|
||||||
\
|
|
||||||
Py_DECREF(_module); \
|
|
||||||
if (_c_api != NULL && PyCapsule_CheckExact(_c_api)) { \
|
|
||||||
void **localptr = (void **)PyCapsule_GetPointer( \
|
|
||||||
_c_api, PG_CAPSULE_NAME(#module)); \
|
|
||||||
_PGSLOTS_ ## module = localptr; \
|
|
||||||
} \
|
|
||||||
Py_XDECREF(_c_api); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PYGAMEAPI_IS_IMPORTED(module) (_PGSLOTS_ ## module != NULL)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* source file must include one of these in order to use _IMPORT_PYGAME_MODULE.
|
|
||||||
* this is set by import_pygame_*() functions.
|
|
||||||
* disable with NO_PYGAME_C_API
|
|
||||||
*/
|
|
||||||
#define PYGAMEAPI_DEFINE_SLOTS(module) \
|
|
||||||
void ** _PGSLOTS_ ## module = NULL
|
|
||||||
#define PYGAMEAPI_EXTERN_SLOTS(module) \
|
|
||||||
extern void **_PGSLOTS_ ## module
|
|
||||||
#define PYGAMEAPI_GET_SLOT(module, index) \
|
|
||||||
_PGSLOTS_ ## module [(index)]
|
|
||||||
|
|
||||||
/*
|
|
||||||
* disabled API with NO_PYGAME_C_API; do nothing instead
|
|
||||||
*/
|
|
||||||
#ifdef NO_PYGAME_C_API
|
|
||||||
|
|
||||||
#undef PYGAMEAPI_DEFINE_SLOTS
|
|
||||||
#undef PYGAMEAPI_EXTERN_SLOTS
|
|
||||||
|
|
||||||
#define PYGAMEAPI_DEFINE_SLOTS(module)
|
|
||||||
#define PYGAMEAPI_EXTERN_SLOTS(module)
|
|
||||||
|
|
||||||
/* intentionally leave this defined to cause a compiler error *
|
|
||||||
#define PYGAMEAPI_GET_SLOT(api_root, index)
|
|
||||||
#undef PYGAMEAPI_GET_SLOT*/
|
|
||||||
|
|
||||||
#undef _IMPORT_PYGAME_MODULE
|
|
||||||
#define _IMPORT_PYGAME_MODULE(module)
|
|
||||||
|
|
||||||
#endif /* NO_PYGAME_C_API */
|
|
||||||
|
|
||||||
#endif /* ~PGIMPORT_H */
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
/* platform/compiler adjustments */
|
|
||||||
#ifndef PG_PLATFORM_H
|
|
||||||
#define PG_PLATFORM_H
|
|
||||||
|
|
||||||
#if defined(HAVE_SNPRINTF) /* defined in python.h (pyerrors.h) and SDL.h \
|
|
||||||
(SDL_config.h) */
|
|
||||||
#undef HAVE_SNPRINTF /* remove GCC redefine warning */
|
|
||||||
#endif /* HAVE_SNPRINTF */
|
|
||||||
|
|
||||||
#ifndef PG_INLINE
|
|
||||||
#if defined(__clang__)
|
|
||||||
#define PG_INLINE __inline__ __attribute__((__unused__))
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
#define PG_INLINE __inline__
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#define PG_INLINE __inline
|
|
||||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
|
||||||
#define PG_INLINE inline
|
|
||||||
#else
|
|
||||||
#define PG_INLINE
|
|
||||||
#endif
|
|
||||||
#endif /* ~PG_INLINE */
|
|
||||||
|
|
||||||
/* This is unconditionally defined in Python.h */
|
|
||||||
#if defined(_POSIX_C_SOURCE)
|
|
||||||
#undef _POSIX_C_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* No signal() */
|
|
||||||
#if defined(__SYMBIAN32__) && defined(HAVE_SIGNAL_H)
|
|
||||||
#undef HAVE_SIGNAL_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_SNPRINTF)
|
|
||||||
#undef HAVE_SNPRINTF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* SDL needs WIN32 */
|
|
||||||
#if !defined(WIN32) && \
|
|
||||||
(defined(MS_WIN32) || defined(_WIN32) || \
|
|
||||||
defined(__WIN32) || defined(__WIN32__) || defined(_WINDOWS))
|
|
||||||
#define WIN32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ~PG_PLATFORM_H */
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* To allow the Pygame C api to be globally shared by all code within an
|
|
||||||
* extension module built from multiple C files, only include the pygame.h
|
|
||||||
* header within the top level C file, the one which calls the
|
|
||||||
* 'import_pygame_*' macros. All other C source files of the module should
|
|
||||||
* include _pygame.h instead.
|
|
||||||
*/
|
|
||||||
#ifndef PYGAME_H
|
|
||||||
#define PYGAME_H
|
|
||||||
|
|
||||||
#include "_pygame.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
Copyright (C) 2007 Rene Dudfield, Richard Goedeken
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Bufferproxy module C api. */
|
|
||||||
#if !defined(PG_BUFPROXY_HEADER)
|
|
||||||
#define PG_BUFPROXY_HEADER
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
|
|
||||||
typedef PyObject *(*_pgbufproxy_new_t)(PyObject *, getbufferproc);
|
|
||||||
typedef PyObject *(*_pgbufproxy_get_obj_t)(PyObject *);
|
|
||||||
typedef int (*_pgbufproxy_trip_t)(PyObject *);
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_BUFPROXY_INTERNAL
|
|
||||||
|
|
||||||
#include "pgimport.h"
|
|
||||||
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(bufferproxy);
|
|
||||||
|
|
||||||
#define pgBufproxy_Type (*(PyTypeObject*) \
|
|
||||||
PYGAMEAPI_GET_SLOT(bufferproxy, 0) )
|
|
||||||
|
|
||||||
#define pgBufproxy_Check(x) ((x)->ob_type == &pgBufproxy_Type)
|
|
||||||
|
|
||||||
#define pgBufproxy_New (*(_pgbufproxy_new_t) \
|
|
||||||
PYGAMEAPI_GET_SLOT(bufferproxy, 1))
|
|
||||||
|
|
||||||
#define pgBufproxy_GetParent \
|
|
||||||
(*(_pgbufproxy_get_obj_t) \
|
|
||||||
PYGAMEAPI_GET_SLOT(bufferproxy, 2))
|
|
||||||
|
|
||||||
#define pgBufproxy_Trip (*(_pgbufproxy_trip_t) \
|
|
||||||
PYGAMEAPI_GET_SLOT(bufferproxy, 3))
|
|
||||||
|
|
||||||
#define import_pygame_bufferproxy() _IMPORT_PYGAME_MODULE(bufferproxy)
|
|
||||||
|
|
||||||
#endif /* ~PYGAMEAPI_BUFPROXY_INTERNAL */
|
|
||||||
|
|
||||||
#endif /* ~defined(PG_BUFPROXY_HEADER) */
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
#include "pgplatform.h"
|
|
||||||
|
|
||||||
struct TTF_Font;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
TTF_Font* font;
|
|
||||||
PyObject* weakreflist;
|
|
||||||
} PyFontObject;
|
|
||||||
#define PyFont_AsFont(x) (((PyFontObject*)x)->font)
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_FONT_INTERNAL
|
|
||||||
|
|
||||||
#include "pgimport.h"
|
|
||||||
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(font);
|
|
||||||
|
|
||||||
#define PyFont_Type (*(PyTypeObject*) \
|
|
||||||
PYGAMEAPI_GET_SLOT(font, 0))
|
|
||||||
#define PyFont_Check(x) ((x)->ob_type == &PyFont_Type)
|
|
||||||
|
|
||||||
#define PyFont_New (*(PyObject*(*)(TTF_Font*))\
|
|
||||||
PYGAMEAPI_GET_SLOT(font, 1))
|
|
||||||
|
|
||||||
/*slot 2 taken by FONT_INIT_CHECK*/
|
|
||||||
|
|
||||||
#define import_pygame_font() _IMPORT_PYGAME_MODULE(font)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2009 Vicent Marti
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef PYGAME_FREETYPE_H_
|
|
||||||
#define PYGAME_FREETYPE_H_
|
|
||||||
|
|
||||||
#include "pgplatform.h"
|
|
||||||
#include "pgimport.h"
|
|
||||||
#include "pgcompat.h"
|
|
||||||
|
|
||||||
#ifndef PYGAME_FREETYPE_INTERNAL
|
|
||||||
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(_freetype);
|
|
||||||
|
|
||||||
#define pgFont_Type (*(PyTypeObject*) \
|
|
||||||
PYGAMEAPI_GET_SLOT(_freetype, 0))
|
|
||||||
|
|
||||||
#define pgFont_Check(x) ((x)->ob_type == &pgFont_Type)
|
|
||||||
|
|
||||||
#define pgFont_New (*(PyObject*(*)(const char*, long)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(_freetype, 1))
|
|
||||||
|
|
||||||
#define import_pygame_freetype() _IMPORT_PYGAME_MODULE(_freetype)
|
|
||||||
|
|
||||||
#endif /* PYGAME_FREETYPE_INTERNAL */
|
|
||||||
|
|
||||||
#endif /* PYGAME_FREETYPE_H_ */
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PGMASK_H
|
|
||||||
#define PGMASK_H
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
#include "bitmask.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
bitmask_t *mask;
|
|
||||||
void *bufdata;
|
|
||||||
} pgMaskObject;
|
|
||||||
|
|
||||||
#define pgMask_AsBitmap(x) (((pgMaskObject*)x)->mask)
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_MASK_INTERNAL
|
|
||||||
|
|
||||||
#include "pgimport.h"
|
|
||||||
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(mask);
|
|
||||||
|
|
||||||
#define pgMask_Type (*(PyTypeObject*) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mask, 0))
|
|
||||||
#define pgMask_Check(x) ((x)->ob_type == &pgMask_Type)
|
|
||||||
|
|
||||||
#define import_pygame_mask() _IMPORT_PYGAME_MODULE(mask)
|
|
||||||
|
|
||||||
#endif /* ~PYGAMEAPI_MASK_INTERNAL */
|
|
||||||
|
|
||||||
#endif /* ~PGMASK_H */
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PGMIXER_H
|
|
||||||
#define PGMIXER_H
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
#include <structmember.h>
|
|
||||||
|
|
||||||
#include "pgcompat.h"
|
|
||||||
|
|
||||||
struct Mix_Chunk;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
Mix_Chunk *chunk;
|
|
||||||
Uint8 *mem;
|
|
||||||
PyObject *weakreflist;
|
|
||||||
} pgSoundObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
int chan;
|
|
||||||
} pgChannelObject;
|
|
||||||
|
|
||||||
#define pgSound_AsChunk(x) (((pgSoundObject*)x)->chunk)
|
|
||||||
#define pgChannel_AsInt(x) (((pgChannelObject*)x)->chan)
|
|
||||||
|
|
||||||
#include "pgimport.h"
|
|
||||||
|
|
||||||
#ifndef PYGAMEAPI_MIXER_INTERNAL
|
|
||||||
|
|
||||||
PYGAMEAPI_DEFINE_SLOTS(mixer);
|
|
||||||
|
|
||||||
#define pgSound_Type (*(PyTypeObject*) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mixer, 0))
|
|
||||||
|
|
||||||
#define pgSound_Check(x) ((x)->ob_type == &pgSound_Type)
|
|
||||||
|
|
||||||
#define pgSound_New (*(PyObject*(*)(Mix_Chunk*)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mixer, 1))
|
|
||||||
|
|
||||||
#define pgSound_Play (*(PyObject*(*)(PyObject*, PyObject*)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mixer, 2))
|
|
||||||
|
|
||||||
#define pgChannel_Type (*(PyTypeObject*) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mixer, 3))
|
|
||||||
#define pgChannel_Check(x) ((x)->ob_type == &pgChannel_Type)
|
|
||||||
|
|
||||||
#define pgChannel_New (*(PyObject*(*)(int)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mixer, 4))
|
|
||||||
|
|
||||||
#define pgMixer_AutoInit (*(PyObject*(*)(PyObject*, PyObject*)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mixer, 5))
|
|
||||||
|
|
||||||
#define pgMixer_AutoQuit (*(void(*)(void)) \
|
|
||||||
PYGAMEAPI_GET_SLOT(mixer, 6))
|
|
||||||
|
|
||||||
#define import_pygame_mixer() _IMPORT_PYGAME_MODULE(mixer)
|
|
||||||
|
|
||||||
#endif /* PYGAMEAPI_MIXER_INTERNAL */
|
|
||||||
|
|
||||||
#endif /* ~PGMIXER_H */
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#ifndef PGMASK_INTERNAL_H
|
|
||||||
#define PGMASK_INTERNAL_H
|
|
||||||
|
|
||||||
#include "include/pygame_mask.h"
|
|
||||||
#define PYGAMEAPI_MASK_NUMSLOTS 1
|
|
||||||
|
|
||||||
#endif /* ~PGMASK_INTERNAL_H */
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef MIXER_INTERNAL_H
|
|
||||||
#define MIXER_INTERNAL_H
|
|
||||||
|
|
||||||
#include <SDL_mixer.h>
|
|
||||||
|
|
||||||
/* test mixer initializations */
|
|
||||||
#define MIXER_INIT_CHECK() \
|
|
||||||
if(!SDL_WasInit(SDL_INIT_AUDIO)) \
|
|
||||||
return RAISE(pgExc_SDLError, "mixer not initialized")
|
|
||||||
|
|
||||||
#define PYGAMEAPI_MIXER_NUMSLOTS 7
|
|
||||||
#include "include/pygame_mixer.h"
|
|
||||||
|
|
||||||
#endif /* ~MIXER_INTERNAL_H */
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PALETTE_H
|
|
||||||
#define PALETTE_H
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
/* SDL 2 does not assign a default palette color scheme to a new 8 bit
|
|
||||||
* surface. Instead, the palette is set all white. This defines the SDL 1.2
|
|
||||||
* default palette.
|
|
||||||
*/
|
|
||||||
static const SDL_Color default_palette_colors[] = {
|
|
||||||
{0, 0, 0, 255}, {0, 0, 85, 255}, {0, 0, 170, 255},
|
|
||||||
{0, 0, 255, 255}, {0, 36, 0, 255}, {0, 36, 85, 255},
|
|
||||||
{0, 36, 170, 255}, {0, 36, 255, 255}, {0, 73, 0, 255},
|
|
||||||
{0, 73, 85, 255}, {0, 73, 170, 255}, {0, 73, 255, 255},
|
|
||||||
{0, 109, 0, 255}, {0, 109, 85, 255}, {0, 109, 170, 255},
|
|
||||||
{0, 109, 255, 255}, {0, 146, 0, 255}, {0, 146, 85, 255},
|
|
||||||
{0, 146, 170, 255}, {0, 146, 255, 255}, {0, 182, 0, 255},
|
|
||||||
{0, 182, 85, 255}, {0, 182, 170, 255}, {0, 182, 255, 255},
|
|
||||||
{0, 219, 0, 255}, {0, 219, 85, 255}, {0, 219, 170, 255},
|
|
||||||
{0, 219, 255, 255}, {0, 255, 0, 255}, {0, 255, 85, 255},
|
|
||||||
{0, 255, 170, 255}, {0, 255, 255, 255}, {85, 0, 0, 255},
|
|
||||||
{85, 0, 85, 255}, {85, 0, 170, 255}, {85, 0, 255, 255},
|
|
||||||
{85, 36, 0, 255}, {85, 36, 85, 255}, {85, 36, 170, 255},
|
|
||||||
{85, 36, 255, 255}, {85, 73, 0, 255}, {85, 73, 85, 255},
|
|
||||||
{85, 73, 170, 255}, {85, 73, 255, 255}, {85, 109, 0, 255},
|
|
||||||
{85, 109, 85, 255}, {85, 109, 170, 255}, {85, 109, 255, 255},
|
|
||||||
{85, 146, 0, 255}, {85, 146, 85, 255}, {85, 146, 170, 255},
|
|
||||||
{85, 146, 255, 255}, {85, 182, 0, 255}, {85, 182, 85, 255},
|
|
||||||
{85, 182, 170, 255}, {85, 182, 255, 255}, {85, 219, 0, 255},
|
|
||||||
{85, 219, 85, 255}, {85, 219, 170, 255}, {85, 219, 255, 255},
|
|
||||||
{85, 255, 0, 255}, {85, 255, 85, 255}, {85, 255, 170, 255},
|
|
||||||
{85, 255, 255, 255}, {170, 0, 0, 255}, {170, 0, 85, 255},
|
|
||||||
{170, 0, 170, 255}, {170, 0, 255, 255}, {170, 36, 0, 255},
|
|
||||||
{170, 36, 85, 255}, {170, 36, 170, 255}, {170, 36, 255, 255},
|
|
||||||
{170, 73, 0, 255}, {170, 73, 85, 255}, {170, 73, 170, 255},
|
|
||||||
{170, 73, 255, 255}, {170, 109, 0, 255}, {170, 109, 85, 255},
|
|
||||||
{170, 109, 170, 255}, {170, 109, 255, 255}, {170, 146, 0, 255},
|
|
||||||
{170, 146, 85, 255}, {170, 146, 170, 255}, {170, 146, 255, 255},
|
|
||||||
{170, 182, 0, 255}, {170, 182, 85, 255}, {170, 182, 170, 255},
|
|
||||||
{170, 182, 255, 255}, {170, 219, 0, 255}, {170, 219, 85, 255},
|
|
||||||
{170, 219, 170, 255}, {170, 219, 255, 255}, {170, 255, 0, 255},
|
|
||||||
{170, 255, 85, 255}, {170, 255, 170, 255}, {170, 255, 255, 255},
|
|
||||||
{255, 0, 0, 255}, {255, 0, 85, 255}, {255, 0, 170, 255},
|
|
||||||
{255, 0, 255, 255}, {255, 36, 0, 255}, {255, 36, 85, 255},
|
|
||||||
{255, 36, 170, 255}, {255, 36, 255, 255}, {255, 73, 0, 255},
|
|
||||||
{255, 73, 85, 255}, {255, 73, 170, 255}, {255, 73, 255, 255},
|
|
||||||
{255, 109, 0, 255}, {255, 109, 85, 255}, {255, 109, 170, 255},
|
|
||||||
{255, 109, 255, 255}, {255, 146, 0, 255}, {255, 146, 85, 255},
|
|
||||||
{255, 146, 170, 255}, {255, 146, 255, 255}, {255, 182, 0, 255},
|
|
||||||
{255, 182, 85, 255}, {255, 182, 170, 255}, {255, 182, 255, 255},
|
|
||||||
{255, 219, 0, 255}, {255, 219, 85, 255}, {255, 219, 170, 255},
|
|
||||||
{255, 219, 255, 255}, {255, 255, 0, 255}, {255, 255, 85, 255},
|
|
||||||
{255, 255, 170, 255}, {255, 255, 255, 255}, {0, 0, 0, 255},
|
|
||||||
{0, 0, 85, 255}, {0, 0, 170, 255}, {0, 0, 255, 255},
|
|
||||||
{0, 36, 0, 255}, {0, 36, 85, 255}, {0, 36, 170, 255},
|
|
||||||
{0, 36, 255, 255}, {0, 73, 0, 255}, {0, 73, 85, 255},
|
|
||||||
{0, 73, 170, 255}, {0, 73, 255, 255}, {0, 109, 0, 255},
|
|
||||||
{0, 109, 85, 255}, {0, 109, 170, 255}, {0, 109, 255, 255},
|
|
||||||
{0, 146, 0, 255}, {0, 146, 85, 255}, {0, 146, 170, 255},
|
|
||||||
{0, 146, 255, 255}, {0, 182, 0, 255}, {0, 182, 85, 255},
|
|
||||||
{0, 182, 170, 255}, {0, 182, 255, 255}, {0, 219, 0, 255},
|
|
||||||
{0, 219, 85, 255}, {0, 219, 170, 255}, {0, 219, 255, 255},
|
|
||||||
{0, 255, 0, 255}, {0, 255, 85, 255}, {0, 255, 170, 255},
|
|
||||||
{0, 255, 255, 255}, {85, 0, 0, 255}, {85, 0, 85, 255},
|
|
||||||
{85, 0, 170, 255}, {85, 0, 255, 255}, {85, 36, 0, 255},
|
|
||||||
{85, 36, 85, 255}, {85, 36, 170, 255}, {85, 36, 255, 255},
|
|
||||||
{85, 73, 0, 255}, {85, 73, 85, 255}, {85, 73, 170, 255},
|
|
||||||
{85, 73, 255, 255}, {85, 109, 0, 255}, {85, 109, 85, 255},
|
|
||||||
{85, 109, 170, 255}, {85, 109, 255, 255}, {85, 146, 0, 255},
|
|
||||||
{85, 146, 85, 255}, {85, 146, 170, 255}, {85, 146, 255, 255},
|
|
||||||
{85, 182, 0, 255}, {85, 182, 85, 255}, {85, 182, 170, 255},
|
|
||||||
{85, 182, 255, 255}, {85, 219, 0, 255}, {85, 219, 85, 255},
|
|
||||||
{85, 219, 170, 255}, {85, 219, 255, 255}, {85, 255, 0, 255},
|
|
||||||
{85, 255, 85, 255}, {85, 255, 170, 255}, {85, 255, 255, 255},
|
|
||||||
{170, 0, 0, 255}, {170, 0, 85, 255}, {170, 0, 170, 255},
|
|
||||||
{170, 0, 255, 255}, {170, 36, 0, 255}, {170, 36, 85, 255},
|
|
||||||
{170, 36, 170, 255}, {170, 36, 255, 255}, {170, 73, 0, 255},
|
|
||||||
{170, 73, 85, 255}, {170, 73, 170, 255}, {170, 73, 255, 255},
|
|
||||||
{170, 109, 0, 255}, {170, 109, 85, 255}, {170, 109, 170, 255},
|
|
||||||
{170, 109, 255, 255}, {170, 146, 0, 255}, {170, 146, 85, 255},
|
|
||||||
{170, 146, 170, 255}, {170, 146, 255, 255}, {170, 182, 0, 255},
|
|
||||||
{170, 182, 85, 255}, {170, 182, 170, 255}, {170, 182, 255, 255},
|
|
||||||
{170, 219, 0, 255}, {170, 219, 85, 255}, {170, 219, 170, 255},
|
|
||||||
{170, 219, 255, 255}, {170, 255, 0, 255}, {170, 255, 85, 255},
|
|
||||||
{170, 255, 170, 255}, {170, 255, 255, 255}, {255, 0, 0, 255},
|
|
||||||
{255, 0, 85, 255}, {255, 0, 170, 255}, {255, 0, 255, 255},
|
|
||||||
{255, 36, 0, 255}, {255, 36, 85, 255}, {255, 36, 170, 255},
|
|
||||||
{255, 36, 255, 255}, {255, 73, 0, 255}, {255, 73, 85, 255},
|
|
||||||
{255, 73, 170, 255}, {255, 73, 255, 255}, {255, 109, 0, 255},
|
|
||||||
{255, 109, 85, 255}, {255, 109, 170, 255}, {255, 109, 255, 255},
|
|
||||||
{255, 146, 0, 255}, {255, 146, 85, 255}, {255, 146, 170, 255},
|
|
||||||
{255, 146, 255, 255}, {255, 182, 0, 255}, {255, 182, 85, 255},
|
|
||||||
{255, 182, 170, 255}, {255, 182, 255, 255}, {255, 219, 0, 255},
|
|
||||||
{255, 219, 85, 255}, {255, 219, 170, 255}, {255, 219, 255, 255},
|
|
||||||
{255, 255, 0, 255}, {255, 255, 85, 255}, {255, 255, 170, 255},
|
|
||||||
{255, 255, 255, 255}};
|
|
||||||
|
|
||||||
static const int default_palette_size =
|
|
||||||
(int)(sizeof(default_palette_colors) / sizeof(SDL_Color));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
/* array structure interface version 3 declarations */
|
|
||||||
|
|
||||||
#if !defined(PG_ARRAYINTER_HEADER)
|
|
||||||
#define PG_ARRAYINTER_HEADER
|
|
||||||
|
|
||||||
static const int PAI_CONTIGUOUS = 0x01;
|
|
||||||
static const int PAI_FORTRAN = 0x02;
|
|
||||||
static const int PAI_ALIGNED = 0x100;
|
|
||||||
static const int PAI_NOTSWAPPED = 0x200;
|
|
||||||
static const int PAI_WRITEABLE = 0x400;
|
|
||||||
static const int PAI_ARR_HAS_DESCR = 0x800;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int two; /* contains the integer 2 -- simple sanity check */
|
|
||||||
int nd; /* number of dimensions */
|
|
||||||
char typekind; /* kind in array -- character code of typestr */
|
|
||||||
int itemsize; /* size of each element */
|
|
||||||
int flags; /* flags indicating how the data should be */
|
|
||||||
/* interpreted */
|
|
||||||
Py_intptr_t *shape; /* A length-nd array of shape information */
|
|
||||||
Py_intptr_t *strides; /* A length-nd array of stride information */
|
|
||||||
void *data; /* A pointer to the first element of the array */
|
|
||||||
PyObject *descr; /* NULL or a data-description */
|
|
||||||
} PyArrayInterface;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
#ifndef PG_BUFPROXY_INTERNAL_H
|
|
||||||
#define PG_BUFPROXY_INTERNAL_H
|
|
||||||
|
|
||||||
#include "include/pygame_bufferproxy.h"
|
|
||||||
#define PYGAMEAPI_BUFPROXY_NUMSLOTS 4
|
|
||||||
|
|
||||||
#endif /* ~PG_BUFPROXY_INTERNAL_H */
|
|
||||||
|
|
@ -1,214 +0,0 @@
|
||||||
/* Python 2.x/3.x compatibility tools (internal)
|
|
||||||
*/
|
|
||||||
#ifndef PGCOMPAT_INTERNAL_H
|
|
||||||
#define PGCOMPAT_INTERNAL_H
|
|
||||||
|
|
||||||
#include "include/pgcompat.h"
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
|
|
||||||
#define PY3 1
|
|
||||||
|
|
||||||
/* Define some aliases for the removed PyInt_* functions */
|
|
||||||
#define PyInt_Check(op) PyLong_Check(op)
|
|
||||||
#define PyInt_FromString PyLong_FromString
|
|
||||||
#define PyInt_FromUnicode PyLong_FromUnicode
|
|
||||||
#define PyInt_FromLong PyLong_FromLong
|
|
||||||
#define PyInt_FromSize_t PyLong_FromSize_t
|
|
||||||
#define PyInt_FromSsize_t PyLong_FromSsize_t
|
|
||||||
#define PyInt_AsLong PyLong_AsLong
|
|
||||||
#define PyInt_AsSsize_t PyLong_AsSsize_t
|
|
||||||
#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
|
|
||||||
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
|
|
||||||
#define PyInt_AS_LONG PyLong_AS_LONG
|
|
||||||
#define PyNumber_Int PyNumber_Long
|
|
||||||
|
|
||||||
/* Weakrefs flags changed in 3.x */
|
|
||||||
#define Py_TPFLAGS_HAVE_WEAKREFS 0
|
|
||||||
|
|
||||||
/* Module init function returns new module instance. */
|
|
||||||
#define MODINIT_RETURN(x) return x
|
|
||||||
#define MODINIT_DEFINE(mod_name) PyMODINIT_FUNC PyInit_##mod_name (void)
|
|
||||||
#define DECREF_MOD(mod) Py_DECREF (mod)
|
|
||||||
|
|
||||||
/* Type header differs. */
|
|
||||||
#define TYPE_HEAD(x,y) PyVarObject_HEAD_INIT(x,y)
|
|
||||||
|
|
||||||
/* Text interface. Use unicode strings. */
|
|
||||||
#define Text_Type PyUnicode_Type
|
|
||||||
#define Text_Check PyUnicode_Check
|
|
||||||
|
|
||||||
#ifndef PYPY_VERSION
|
|
||||||
#define Text_FromLocale(s) PyUnicode_DecodeLocale((s), "strict")
|
|
||||||
#else /* PYPY_VERSION */
|
|
||||||
/* workaround: missing function for pypy */
|
|
||||||
#define Text_FromLocale PyUnicode_FromString
|
|
||||||
#endif /* PYPY_VERSION */
|
|
||||||
|
|
||||||
#define Text_FromUTF8 PyUnicode_FromString
|
|
||||||
#define Text_FromUTF8AndSize PyUnicode_FromStringAndSize
|
|
||||||
#define Text_FromFormat PyUnicode_FromFormat
|
|
||||||
#define Text_GetSize PyUnicode_GetSize
|
|
||||||
#define Text_GET_SIZE PyUnicode_GET_SIZE
|
|
||||||
|
|
||||||
/* Binary interface. Use bytes. */
|
|
||||||
#define Bytes_Type PyBytes_Type
|
|
||||||
#define Bytes_Check PyBytes_Check
|
|
||||||
#define Bytes_Size PyBytes_Size
|
|
||||||
#define Bytes_AsString PyBytes_AsString
|
|
||||||
#define Bytes_AsStringAndSize PyBytes_AsStringAndSize
|
|
||||||
#define Bytes_FromStringAndSize PyBytes_FromStringAndSize
|
|
||||||
#define Bytes_FromFormat PyBytes_FromFormat
|
|
||||||
#define Bytes_AS_STRING PyBytes_AS_STRING
|
|
||||||
#define Bytes_GET_SIZE PyBytes_GET_SIZE
|
|
||||||
#define Bytes_AsDecodeObject PyBytes_AsDecodedObject
|
|
||||||
|
|
||||||
#define Object_Unicode PyObject_Str
|
|
||||||
|
|
||||||
#define IsTextObj(x) (PyUnicode_Check(x) || PyBytes_Check(x))
|
|
||||||
|
|
||||||
/* Renamed builtins */
|
|
||||||
#define BUILTINS_MODULE "builtins"
|
|
||||||
#define BUILTINS_UNICODE "str"
|
|
||||||
#define BUILTINS_UNICHR "chr"
|
|
||||||
|
|
||||||
/* Defaults for unicode file path encoding */
|
|
||||||
#define UNICODE_DEF_FS_CODEC Py_FileSystemDefaultEncoding
|
|
||||||
#if defined(MS_WIN32)
|
|
||||||
#define UNICODE_DEF_FS_ERROR "replace"
|
|
||||||
#else
|
|
||||||
#define UNICODE_DEF_FS_ERROR "surrogateescape"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* #if PY_MAJOR_VERSION >= 3 */
|
|
||||||
|
|
||||||
#define PY3 0
|
|
||||||
|
|
||||||
/* Module init function returns nothing. */
|
|
||||||
#define MODINIT_RETURN(x) return
|
|
||||||
#define MODINIT_DEFINE(mod_name) PyMODINIT_FUNC init##mod_name (void)
|
|
||||||
#define DECREF_MOD(mod)
|
|
||||||
|
|
||||||
/* Type header differs. */
|
|
||||||
#define TYPE_HEAD(x,y) \
|
|
||||||
PyObject_HEAD_INIT(x) \
|
|
||||||
0,
|
|
||||||
|
|
||||||
/* Text interface. Use ascii strings. */
|
|
||||||
#define Text_Type PyString_Type
|
|
||||||
#define Text_Check PyString_Check
|
|
||||||
#define Text_FromLocale PyString_FromString
|
|
||||||
#define Text_FromUTF8 PyString_FromString
|
|
||||||
#define Text_FromUTF8AndSize PyString_FromStringAndSize
|
|
||||||
#define Text_FromFormat PyString_FromFormat
|
|
||||||
#define Text_GetSize PyString_GetSize
|
|
||||||
#define Text_GET_SIZE PyString_GET_SIZE
|
|
||||||
|
|
||||||
/* Binary interface. Use ascii strings. */
|
|
||||||
#define Bytes_Type PyString_Type
|
|
||||||
#define Bytes_Check PyString_Check
|
|
||||||
#define Bytes_Size PyString_Size
|
|
||||||
#define Bytes_AsString PyString_AsString
|
|
||||||
#define Bytes_AsStringAndSize PyString_AsStringAndSize
|
|
||||||
#define Bytes_FromStringAndSize PyString_FromStringAndSize
|
|
||||||
#define Bytes_FromFormat PyString_FromFormat
|
|
||||||
#define Bytes_AS_STRING PyString_AS_STRING
|
|
||||||
#define Bytes_GET_SIZE PyString_GET_SIZE
|
|
||||||
#define Bytes_AsDecodedObject PyString_AsDecodedObject
|
|
||||||
|
|
||||||
#define Object_Unicode PyObject_Unicode
|
|
||||||
|
|
||||||
/* Renamed builtins */
|
|
||||||
#define BUILTINS_MODULE "__builtin__"
|
|
||||||
#define BUILTINS_UNICODE "unicode"
|
|
||||||
#define BUILTINS_UNICHR "unichr"
|
|
||||||
|
|
||||||
/* Defaults for unicode file path encoding */
|
|
||||||
#define UNICODE_DEF_FS_CODEC Py_FileSystemDefaultEncoding
|
|
||||||
#define UNICODE_DEF_FS_ERROR "strict"
|
|
||||||
|
|
||||||
#endif /* #if PY_MAJOR_VERSION >= 3 */
|
|
||||||
|
|
||||||
#define PY2 (!PY3)
|
|
||||||
|
|
||||||
#define MODINIT_ERROR MODINIT_RETURN (NULL)
|
|
||||||
|
|
||||||
/* Module state. These macros are used to define per-module macros.
|
|
||||||
* v - global state variable (Python 2.x)
|
|
||||||
* s - global state structure (Python 3.x)
|
|
||||||
*/
|
|
||||||
#define PY2_GETSTATE(v) (&(v))
|
|
||||||
#define PY3_GETSTATE(s, m) ((struct s *) PyModule_GetState (m))
|
|
||||||
|
|
||||||
/* Pep 3123: Making PyObject_HEAD conform to standard C */
|
|
||||||
#if !defined(Py_TYPE)
|
|
||||||
#define Py_TYPE(o) (((PyObject *)(o))->ob_type)
|
|
||||||
#define Py_REFCNT(o) (((PyObject *)(o))->ob_refcnt)
|
|
||||||
#define Py_SIZE(o) (((PyVarObject *)(o))->ob_size)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Encode a unicode file path */
|
|
||||||
#define Unicode_AsEncodedPath(u) \
|
|
||||||
PyUnicode_AsEncodedString ((u), UNICODE_DEF_FS_CODEC, UNICODE_DEF_FS_ERROR)
|
|
||||||
|
|
||||||
#define RELATIVE_MODULE(m) ("." m)
|
|
||||||
|
|
||||||
#define HAVE_OLD_BUFPROTO PY2
|
|
||||||
|
|
||||||
#if !defined(PG_ENABLE_OLDBUF) /* allow for command line override */
|
|
||||||
#if HAVE_OLD_BUFPROTO
|
|
||||||
#define PG_ENABLE_OLDBUF 1
|
|
||||||
#else
|
|
||||||
#define PG_ENABLE_OLDBUF 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_TPFLAGS_HAVE_NEWBUFFER
|
|
||||||
#define Py_TPFLAGS_HAVE_NEWBUFFER 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_TPFLAGS_HAVE_CLASS
|
|
||||||
#define Py_TPFLAGS_HAVE_CLASS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_TPFLAGS_CHECKTYPES
|
|
||||||
#define Py_TPFLAGS_CHECKTYPES 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PY_VERSION_HEX >= 0x03020000
|
|
||||||
#define Slice_GET_INDICES_EX(slice, length, start, stop, step, slicelength) \
|
|
||||||
PySlice_GetIndicesEx(slice, length, start, stop, step, slicelength)
|
|
||||||
#else
|
|
||||||
#define Slice_GET_INDICES_EX(slice, length, start, stop, step, slicelength) \
|
|
||||||
PySlice_GetIndicesEx((PySliceObject *)(slice), length, \
|
|
||||||
start, stop, step, slicelength)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Support new buffer protocol? */
|
|
||||||
#if !defined(PG_ENABLE_NEWBUF) /* allow for command line override */
|
|
||||||
#if !defined(PYPY_VERSION)
|
|
||||||
#define PG_ENABLE_NEWBUF 1
|
|
||||||
#else
|
|
||||||
#define PG_ENABLE_NEWBUF 0
|
|
||||||
#endif
|
|
||||||
#endif /* !defined(PG_ENABLE_NEWBUF) */
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(SDL_VERSION_ATLEAST)
|
|
||||||
#if !(SDL_VERSION_ATLEAST(2, 0, 5))
|
|
||||||
/* These functions require SDL 2.0.5 or greater.
|
|
||||||
|
|
||||||
https://wiki.libsdl.org/SDL_SetWindowResizable
|
|
||||||
*/
|
|
||||||
void SDL_SetWindowResizable(SDL_Window *window, SDL_bool resizable);
|
|
||||||
int SDL_GetWindowOpacity(SDL_Window *window, float *opacity);
|
|
||||||
int SDL_SetWindowOpacity(SDL_Window *window, float opacity);
|
|
||||||
int SDL_SetWindowModalFor(SDL_Window *modal_window, SDL_Window *parent_window);
|
|
||||||
int SDL_SetWindowInputFocus(SDL_Window *window);
|
|
||||||
SDL_Surface * SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth,
|
|
||||||
Uint32 format);
|
|
||||||
#endif
|
|
||||||
#endif /* defined(SDL_VERSION_ATLEAST) */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ~PGCOMPAT_INTERNAL_H */
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
#ifndef PGIMPORT_INTERNAL_H
|
|
||||||
#define PGIMPORT_INTERNAL_H
|
|
||||||
|
|
||||||
#include "include/pgimport.h"
|
|
||||||
|
|
||||||
#if PG_HAVE_CAPSULE
|
|
||||||
#define encapsulate_api(ptr, module) \
|
|
||||||
PyCapsule_New(ptr, PG_CAPSULE_NAME(module), NULL)
|
|
||||||
#else /* ~PG_HAVE_CAPSULE */
|
|
||||||
#define encapsulate_api(ptr, module) PyCObject_FromVoidPtr(ptr, NULL)
|
|
||||||
#endif /* ~PG_HAVE_CAPSULE */
|
|
||||||
|
|
||||||
#endif /* PGIMPORT_INTERNAL_H */
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
#if !defined(PGOPENGL_H)
|
|
||||||
#define PGOPENGL_H
|
|
||||||
|
|
||||||
/** This header includes definitions of Opengl functions as pointer types for
|
|
||||||
** use with the SDL function SDL_GL_GetProcAddress.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#define GL_APIENTRY __stdcall
|
|
||||||
#else
|
|
||||||
#define GL_APIENTRY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void (GL_APIENTRY *GL_glReadPixels_Func)(int, int, int, int, unsigned int, unsigned int, void*);
|
|
||||||
|
|
||||||
typedef void (GL_APIENTRY *GL_glViewport_Func)(int, int, unsigned int, unsigned int);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
/* platform/compiler adjustments (internal) */
|
|
||||||
#ifndef PG_PLATFORM_INTERNAL_H
|
|
||||||
#define PG_PLATFORM_INTERNAL_H
|
|
||||||
|
|
||||||
/* This must be before all else */
|
|
||||||
#if defined(__SYMBIAN32__) && defined(OPENC)
|
|
||||||
#include <sys/types.h>
|
|
||||||
#if defined(__WINS__)
|
|
||||||
void *
|
|
||||||
_alloca(size_t size);
|
|
||||||
#define alloca _alloca
|
|
||||||
#endif /* __WINS__ */
|
|
||||||
#endif /* defined(__SYMBIAN32__) && defined(OPENC) */
|
|
||||||
|
|
||||||
#include "include/pgplatform.h"
|
|
||||||
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
#ifndef MAX
|
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
#ifndef ABS
|
|
||||||
#define ABS(a) (((a) < 0) ? -(a) : (a))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(macintosh) && defined(__MWERKS__) || defined(__SYMBIAN32__)
|
|
||||||
#define PYGAME_EXPORT __declspec(export)
|
|
||||||
#else
|
|
||||||
#define PYGAME_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* warnings */
|
|
||||||
#define PG_STRINGIZE_HELPER(x) #x
|
|
||||||
#define PG_STRINGIZE(x) PG_STRINGIZE_HELPER(x)
|
|
||||||
#define PG_WARN(desc) message(__FILE__ "(" PG_STRINGIZE(__LINE__) "): WARNING: " #desc)
|
|
||||||
|
|
||||||
#endif /* ~PG_PLATFORM_INTERNAL_H */
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This will use PYGAMEAPI_DEFINE_SLOTS instead
|
|
||||||
* of PYGAMEAPI_EXTERN_SLOTS for base modules.
|
|
||||||
*/
|
|
||||||
#ifndef PYGAME_INTERNAL_H
|
|
||||||
#define PYGAME_INTERNAL_H
|
|
||||||
|
|
||||||
#define PYGAME_H
|
|
||||||
#include "_pygame.h"
|
|
||||||
|
|
||||||
#endif /* ~PYGAME_INTERNAL_H */
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2006, 2007 Rene Dudfield, Marcus von Appen
|
|
||||||
|
|
||||||
Originally put in the public domain by Sam Lantinga.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SCRAP_H
|
|
||||||
#define SCRAP_H
|
|
||||||
|
|
||||||
/* This is unconditionally defined in Python.h */
|
|
||||||
#if defined(_POSIX_C_SOURCE)
|
|
||||||
#undef _POSIX_C_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
|
|
||||||
/* Handle clipboard text and data in arbitrary formats */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Predefined supported pygame scrap types.
|
|
||||||
*/
|
|
||||||
#define PYGAME_SCRAP_TEXT "text/plain"
|
|
||||||
#define PYGAME_SCRAP_BMP "image/bmp"
|
|
||||||
#define PYGAME_SCRAP_PPM "image/ppm"
|
|
||||||
#define PYGAME_SCRAP_PBM "image/pbm"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The supported scrap clipboard types.
|
|
||||||
*
|
|
||||||
* This is only relevant in a X11 environment, which supports mouse
|
|
||||||
* selections as well. For Win32 and MacOS environments the default
|
|
||||||
* clipboard is used, no matter what value is passed.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SCRAP_CLIPBOARD,
|
|
||||||
SCRAP_SELECTION /* only supported in X11 environments. */
|
|
||||||
} ScrapClipType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Macro for initialization checks.
|
|
||||||
*/
|
|
||||||
#define PYGAME_SCRAP_INIT_CHECK() \
|
|
||||||
if(!pygame_scrap_initialized()) \
|
|
||||||
return (PyErr_SetString (pgExc_SDLError, \
|
|
||||||
"scrap system not initialized."), NULL)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Checks, whether the pygame scrap module was initialized.
|
|
||||||
*
|
|
||||||
* \return 1 if the modules was initialized, 0 otherwise.
|
|
||||||
*/
|
|
||||||
extern int
|
|
||||||
pygame_scrap_initialized (void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Initializes the pygame scrap module internals. Call this before any
|
|
||||||
* other method.
|
|
||||||
*
|
|
||||||
* \return 1 on successful initialization, 0 otherwise.
|
|
||||||
*/
|
|
||||||
extern int
|
|
||||||
pygame_scrap_init (void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Checks, whether the pygame window lost the clipboard focus or not.
|
|
||||||
*
|
|
||||||
* \return 1 if the window lost the focus, 0 otherwise.
|
|
||||||
*/
|
|
||||||
extern int
|
|
||||||
pygame_scrap_lost (void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Places content of a specific type into the clipboard.
|
|
||||||
*
|
|
||||||
* \note For X11 the following notes are important: The following types
|
|
||||||
* are reserved for internal usage and thus will throw an error on
|
|
||||||
* setting them: "TIMESTAMP", "TARGETS", "SDL_SELECTION".
|
|
||||||
* Setting PYGAME_SCRAP_TEXT ("text/plain") will also automatically
|
|
||||||
* set the X11 types "STRING" (XA_STRING), "TEXT" and "UTF8_STRING".
|
|
||||||
*
|
|
||||||
* For Win32 the following notes are important: Setting
|
|
||||||
* PYGAME_SCRAP_TEXT ("text/plain") will also automatically set
|
|
||||||
* the Win32 type "TEXT" (CF_TEXT).
|
|
||||||
*
|
|
||||||
* For QNX the following notes are important: Setting
|
|
||||||
* PYGAME_SCRAP_TEXT ("text/plain") will also automatically set
|
|
||||||
* the QNX type "TEXT" (Ph_CL_TEXT).
|
|
||||||
*
|
|
||||||
* \param type The type of the content.
|
|
||||||
* \param srclen The length of the content.
|
|
||||||
* \param src The NULL terminated content.
|
|
||||||
* \return 1, if the content could be successfully pasted into the clipboard,
|
|
||||||
* 0 otherwise.
|
|
||||||
*/
|
|
||||||
extern int
|
|
||||||
pygame_scrap_put (char *type, int srclen, char *src);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Gets the current content from the clipboard.
|
|
||||||
*
|
|
||||||
* \note The received content does not need to be the content previously
|
|
||||||
* placed in the clipboard using pygame_put_scrap(). See the
|
|
||||||
* pygame_put_scrap() notes for more details.
|
|
||||||
*
|
|
||||||
* \param type The type of the content to receive.
|
|
||||||
* \param count The size of the returned content.
|
|
||||||
* \return The content or NULL in case of an error or if no content of the
|
|
||||||
* specified type was available.
|
|
||||||
*/
|
|
||||||
extern char*
|
|
||||||
pygame_scrap_get (char *type, unsigned long *count);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Gets the currently available content types from the clipboard.
|
|
||||||
*
|
|
||||||
* \return The different available content types or NULL in case of an
|
|
||||||
* error or if no content type is available.
|
|
||||||
*/
|
|
||||||
extern char**
|
|
||||||
pygame_scrap_get_types (void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Checks whether content for the specified scrap type is currently
|
|
||||||
* available in the clipboard.
|
|
||||||
*
|
|
||||||
* \param type The type to check for.
|
|
||||||
* \return 1, if there is content and 0 otherwise.
|
|
||||||
*/
|
|
||||||
extern int
|
|
||||||
pygame_scrap_contains (char *type);
|
|
||||||
|
|
||||||
#endif /* SCRAP_H */
|
|
||||||
|
|
@ -1,383 +0,0 @@
|
||||||
/*
|
|
||||||
pygame - Python Game Library
|
|
||||||
Copyright (C) 2000-2001 Pete Shinners
|
|
||||||
Copyright (C) 2007 Marcus von Appen
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Pete Shinners
|
|
||||||
pete@shinners.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SURFACE_H
|
|
||||||
#define SURFACE_H
|
|
||||||
|
|
||||||
/* This is defined in SDL.h */
|
|
||||||
#if defined(_POSIX_C_SOURCE)
|
|
||||||
#undef _POSIX_C_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include "pygame.h"
|
|
||||||
|
|
||||||
/* Blend modes */
|
|
||||||
#define PYGAME_BLEND_ADD 0x1
|
|
||||||
#define PYGAME_BLEND_SUB 0x2
|
|
||||||
#define PYGAME_BLEND_MULT 0x3
|
|
||||||
#define PYGAME_BLEND_MIN 0x4
|
|
||||||
#define PYGAME_BLEND_MAX 0x5
|
|
||||||
|
|
||||||
#define PYGAME_BLEND_RGB_ADD 0x1
|
|
||||||
#define PYGAME_BLEND_RGB_SUB 0x2
|
|
||||||
#define PYGAME_BLEND_RGB_MULT 0x3
|
|
||||||
#define PYGAME_BLEND_RGB_MIN 0x4
|
|
||||||
#define PYGAME_BLEND_RGB_MAX 0x5
|
|
||||||
|
|
||||||
#define PYGAME_BLEND_RGBA_ADD 0x6
|
|
||||||
#define PYGAME_BLEND_RGBA_SUB 0x7
|
|
||||||
#define PYGAME_BLEND_RGBA_MULT 0x8
|
|
||||||
#define PYGAME_BLEND_RGBA_MIN 0x9
|
|
||||||
#define PYGAME_BLEND_RGBA_MAX 0x10
|
|
||||||
#define PYGAME_BLEND_PREMULTIPLIED 0x11
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
|
||||||
#define GET_PIXEL_24(b) (b[0] + (b[1] << 8) + (b[2] << 16))
|
|
||||||
#else
|
|
||||||
#define GET_PIXEL_24(b) (b[2] + (b[1] << 8) + (b[0] << 16))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GET_PIXEL(pxl, bpp, source) \
|
|
||||||
switch (bpp) \
|
|
||||||
{ \
|
|
||||||
case 2: \
|
|
||||||
pxl = *((Uint16 *) (source)); \
|
|
||||||
break; \
|
|
||||||
case 4: \
|
|
||||||
pxl = *((Uint32 *) (source)); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
{ \
|
|
||||||
Uint8 *b = (Uint8 *) source; \
|
|
||||||
pxl = GET_PIXEL_24(b); \
|
|
||||||
} \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#if IS_SDLv1
|
|
||||||
#define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa) \
|
|
||||||
_sR = ((px & fmt->Rmask) >> fmt->Rshift); \
|
|
||||||
_sR = (_sR << fmt->Rloss) + (_sR >> (8 - (fmt->Rloss << 1))); \
|
|
||||||
_sG = ((px & fmt->Gmask) >> fmt->Gshift); \
|
|
||||||
_sG = (_sG << fmt->Gloss) + (_sG >> (8 - (fmt->Gloss << 1))); \
|
|
||||||
_sB = ((px & fmt->Bmask) >> fmt->Bshift); \
|
|
||||||
_sB = (_sB << fmt->Bloss) + (_sB >> (8 - (fmt->Bloss << 1))); \
|
|
||||||
if (ppa) \
|
|
||||||
{ \
|
|
||||||
_sA = ((px & fmt->Amask) >> fmt->Ashift); \
|
|
||||||
_sA = (_sA << fmt->Aloss) + (_sA >> (8 - (fmt->Aloss << 1))); \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
{ \
|
|
||||||
_sA = 255; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \
|
|
||||||
sr = _fmt->palette->colors[*((Uint8 *) (_src))].r; \
|
|
||||||
sg = _fmt->palette->colors[*((Uint8 *) (_src))].g; \
|
|
||||||
sb = _fmt->palette->colors[*((Uint8 *) (_src))].b; \
|
|
||||||
sa = 255;
|
|
||||||
|
|
||||||
/* For 1 byte palette pixels */
|
|
||||||
#define SET_PIXELVAL(px, fmt, _dR, _dG, _dB, _dA) \
|
|
||||||
*(px) = (Uint8) SDL_MapRGB(fmt, _dR, _dG, _dB)
|
|
||||||
#else /* IS_SDLv2 */
|
|
||||||
#define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa) \
|
|
||||||
SDL_GetRGBA(px, fmt, &(_sR), &(_sG), &(_sB), &(_sA)); \
|
|
||||||
if (!ppa) { \
|
|
||||||
_sA = 255; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \
|
|
||||||
sr = _fmt->palette->colors[*((Uint8 *) (_src))].r; \
|
|
||||||
sg = _fmt->palette->colors[*((Uint8 *) (_src))].g; \
|
|
||||||
sb = _fmt->palette->colors[*((Uint8 *) (_src))].b; \
|
|
||||||
sa = 255;
|
|
||||||
|
|
||||||
/* For 1 byte palette pixels */
|
|
||||||
#define SET_PIXELVAL(px, fmt, _dR, _dG, _dB, _dA) \
|
|
||||||
*(px) = (Uint8) SDL_MapRGBA(fmt, _dR, _dG, _dB, _dA)
|
|
||||||
#endif /* IS_SDLv2 */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
|
||||||
#define SET_OFFSETS_24(or, og, ob, fmt) \
|
|
||||||
{ \
|
|
||||||
or = (fmt->Rshift == 0 ? 0 : \
|
|
||||||
fmt->Rshift == 8 ? 1 : \
|
|
||||||
2 ); \
|
|
||||||
og = (fmt->Gshift == 0 ? 0 : \
|
|
||||||
fmt->Gshift == 8 ? 1 : \
|
|
||||||
2 ); \
|
|
||||||
ob = (fmt->Bshift == 0 ? 0 : \
|
|
||||||
fmt->Bshift == 8 ? 1 : \
|
|
||||||
2 ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_OFFSETS_32(or, og, ob, fmt) \
|
|
||||||
{ \
|
|
||||||
or = (fmt->Rshift == 0 ? 0 : \
|
|
||||||
fmt->Rshift == 8 ? 1 : \
|
|
||||||
fmt->Rshift == 16 ? 2 : \
|
|
||||||
3 ); \
|
|
||||||
og = (fmt->Gshift == 0 ? 0 : \
|
|
||||||
fmt->Gshift == 8 ? 1 : \
|
|
||||||
fmt->Gshift == 16 ? 2 : \
|
|
||||||
3 ); \
|
|
||||||
ob = (fmt->Bshift == 0 ? 0 : \
|
|
||||||
fmt->Bshift == 8 ? 1 : \
|
|
||||||
fmt->Bshift == 16 ? 2 : \
|
|
||||||
3 ); \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define SET_OFFSETS_24(or, og, ob, fmt) \
|
|
||||||
{ \
|
|
||||||
or = (fmt->Rshift == 0 ? 2 : \
|
|
||||||
fmt->Rshift == 8 ? 1 : \
|
|
||||||
0 ); \
|
|
||||||
og = (fmt->Gshift == 0 ? 2 : \
|
|
||||||
fmt->Gshift == 8 ? 1 : \
|
|
||||||
0 ); \
|
|
||||||
ob = (fmt->Bshift == 0 ? 2 : \
|
|
||||||
fmt->Bshift == 8 ? 1 : \
|
|
||||||
0 ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_OFFSETS_32(or, og, ob, fmt) \
|
|
||||||
{ \
|
|
||||||
or = (fmt->Rshift == 0 ? 3 : \
|
|
||||||
fmt->Rshift == 8 ? 2 : \
|
|
||||||
fmt->Rshift == 16 ? 1 : \
|
|
||||||
0 ); \
|
|
||||||
og = (fmt->Gshift == 0 ? 3 : \
|
|
||||||
fmt->Gshift == 8 ? 2 : \
|
|
||||||
fmt->Gshift == 16 ? 1 : \
|
|
||||||
0 ); \
|
|
||||||
ob = (fmt->Bshift == 0 ? 3 : \
|
|
||||||
fmt->Bshift == 8 ? 2 : \
|
|
||||||
fmt->Bshift == 16 ? 1 : \
|
|
||||||
0 ); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define CREATE_PIXEL(buf, r, g, b, a, bp, ft) \
|
|
||||||
switch (bp) \
|
|
||||||
{ \
|
|
||||||
case 2: \
|
|
||||||
*((Uint16 *) (buf)) = \
|
|
||||||
((r >> ft->Rloss) << ft->Rshift) | \
|
|
||||||
((g >> ft->Gloss) << ft->Gshift) | \
|
|
||||||
((b >> ft->Bloss) << ft->Bshift) | \
|
|
||||||
((a >> ft->Aloss) << ft->Ashift); \
|
|
||||||
break; \
|
|
||||||
case 4: \
|
|
||||||
*((Uint32 *) (buf)) = \
|
|
||||||
((r >> ft->Rloss) << ft->Rshift) | \
|
|
||||||
((g >> ft->Gloss) << ft->Gshift) | \
|
|
||||||
((b >> ft->Bloss) << ft->Bshift) | \
|
|
||||||
((a >> ft->Aloss) << ft->Ashift); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pretty good idea from Tom Duff :-). */
|
|
||||||
#define LOOP_UNROLLED4(code, n, width) \
|
|
||||||
n = (width + 3) / 4; \
|
|
||||||
switch (width & 3) \
|
|
||||||
{ \
|
|
||||||
case 0: do { code; \
|
|
||||||
case 3: code; \
|
|
||||||
case 2: code; \
|
|
||||||
case 1: code; \
|
|
||||||
} while (--n > 0); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Used in the srcbpp == dstbpp == 1 blend functions */
|
|
||||||
#define REPEAT_3(code) \
|
|
||||||
code; \
|
|
||||||
code; \
|
|
||||||
code;
|
|
||||||
|
|
||||||
#define REPEAT_4(code) \
|
|
||||||
code; \
|
|
||||||
code; \
|
|
||||||
code; \
|
|
||||||
code;
|
|
||||||
|
|
||||||
|
|
||||||
#define BLEND_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \
|
|
||||||
tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \
|
|
||||||
tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255);
|
|
||||||
|
|
||||||
#define BLEND_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \
|
|
||||||
tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \
|
|
||||||
tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0);
|
|
||||||
|
|
||||||
#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
dR = (dR && sR) ? (dR * sR) >> 8 : 0; \
|
|
||||||
dG = (dG && sG) ? (dG * sG) >> 8 : 0; \
|
|
||||||
dB = (dB && sB) ? (dB * sB) >> 8 : 0;
|
|
||||||
|
|
||||||
#define BLEND_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
if(sR < dR) { dR = sR; } \
|
|
||||||
if(sG < dG) { dG = sG; } \
|
|
||||||
if(sB < dB) { dB = sB; }
|
|
||||||
|
|
||||||
#define BLEND_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
if(sR > dR) { dR = sR; } \
|
|
||||||
if(sG > dG) { dG = sG; } \
|
|
||||||
if(sB > dB) { dB = sB; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BLEND_RGBA_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \
|
|
||||||
tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \
|
|
||||||
tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255); \
|
|
||||||
tmp = dA + sA; dA = (tmp <= 255 ? tmp : 255);
|
|
||||||
|
|
||||||
#define BLEND_RGBA_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \
|
|
||||||
tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \
|
|
||||||
tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0); \
|
|
||||||
tmp = dA - sA; dA = (tmp >= 0 ? tmp : 0);
|
|
||||||
|
|
||||||
#define BLEND_RGBA_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
dR = (dR && sR) ? (dR * sR) >> 8 : 0; \
|
|
||||||
dG = (dG && sG) ? (dG * sG) >> 8 : 0; \
|
|
||||||
dB = (dB && sB) ? (dB * sB) >> 8 : 0; \
|
|
||||||
dA = (dA && sA) ? (dA * sA) >> 8 : 0;
|
|
||||||
|
|
||||||
#define BLEND_RGBA_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
if(sR < dR) { dR = sR; } \
|
|
||||||
if(sG < dG) { dG = sG; } \
|
|
||||||
if(sB < dB) { dB = sB; } \
|
|
||||||
if(sA < dA) { dA = sA; }
|
|
||||||
|
|
||||||
#define BLEND_RGBA_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
if(sR > dR) { dR = sR; } \
|
|
||||||
if(sG > dG) { dG = sG; } \
|
|
||||||
if(sB > dB) { dB = sB; } \
|
|
||||||
if(sA > dA) { dA = sA; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
/* Choose an alpha blend equation. If the sign is preserved on a right shift
|
|
||||||
* then use a specialized, faster, equation. Otherwise a more general form,
|
|
||||||
* where all additions are done before the shift, is needed.
|
|
||||||
*/
|
|
||||||
#if (-1 >> 1) < 0
|
|
||||||
#define ALPHA_BLEND_COMP(sC, dC, sA) ((((sC - dC) * sA + sC) >> 8) + dC)
|
|
||||||
#else
|
|
||||||
#define ALPHA_BLEND_COMP(sC, dC, sA) (((dC << 8) + (sC - dC) * sA + sC) >> 8)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
do { \
|
|
||||||
if (dA) \
|
|
||||||
{ \
|
|
||||||
dR = ALPHA_BLEND_COMP(sR, dR, sA); \
|
|
||||||
dG = ALPHA_BLEND_COMP(sG, dG, sA); \
|
|
||||||
dB = ALPHA_BLEND_COMP(sB, dB, sA); \
|
|
||||||
dA = sA + dA - ((sA * dA) / 255); \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
{ \
|
|
||||||
dR = sR; \
|
|
||||||
dG = sG; \
|
|
||||||
dB = sB; \
|
|
||||||
dA = sA; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define ALPHA_BLEND_PREMULTIPLIED_COMP(sC, dC, sA) (sC + dC - ((dC * sA) >> 8))
|
|
||||||
|
|
||||||
#define ALPHA_BLEND_PREMULTIPLIED(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
do { \
|
|
||||||
tmp = ALPHA_BLEND_PREMULTIPLIED_COMP(sR, dR, sA); dR = (tmp > 255 ? 255 : tmp); \
|
|
||||||
tmp = ALPHA_BLEND_PREMULTIPLIED_COMP(sG, dG, sA); dG = (tmp > 255 ? 255 : tmp); \
|
|
||||||
tmp = ALPHA_BLEND_PREMULTIPLIED_COMP(sB, dB, sA); dB = (tmp > 255 ? 255 : tmp); \
|
|
||||||
dA = sA + dA - ((sA * dA) / 255); \
|
|
||||||
} while(0)
|
|
||||||
#elif 0
|
|
||||||
|
|
||||||
#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
do { \
|
|
||||||
if(sA){ \
|
|
||||||
if(dA && sA < 255){ \
|
|
||||||
int dContrib = dA*(255 - sA)/255; \
|
|
||||||
dA = sA+dA - ((sA*dA)/255); \
|
|
||||||
dR = (dR*dContrib + sR*sA)/dA; \
|
|
||||||
dG = (dG*dContrib + sG*sA)/dA; \
|
|
||||||
dB = (dB*dContrib + sB*sA)/dA; \
|
|
||||||
}else{ \
|
|
||||||
dR = sR; \
|
|
||||||
dG = sG; \
|
|
||||||
dB = sB; \
|
|
||||||
dA = sA; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
surface_fill_blend (SDL_Surface *surface, SDL_Rect *rect, Uint32 color,
|
|
||||||
int blendargs);
|
|
||||||
|
|
||||||
void
|
|
||||||
surface_respect_clip_rect (SDL_Surface *surface, SDL_Rect *rect);
|
|
||||||
|
|
||||||
int
|
|
||||||
pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect,
|
|
||||||
SDL_Surface * dst, SDL_Rect * dstrect, int the_args);
|
|
||||||
|
|
||||||
int
|
|
||||||
pygame_Blit (SDL_Surface * src, SDL_Rect * srcrect,
|
|
||||||
SDL_Surface * dst, SDL_Rect * dstrect, int the_args);
|
|
||||||
|
|
||||||
#endif /* SURFACE_H */
|
|
||||||
|
|
@ -1,339 +0,0 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Lesser General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) year name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License.
|
|
||||||
|
|
@ -1,510 +0,0 @@
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
|
||||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
|
||||||
specially designated software packages--typically libraries--of the
|
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
|
||||||
can use it too, but we suggest you first think carefully about whether
|
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations
|
|
||||||
below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
|
||||||
not price. Our General Public Licenses are designed to make sure that
|
|
||||||
you have the freedom to distribute copies of free software (and charge
|
|
||||||
for this service if you wish); that you receive source code or can get
|
|
||||||
it if you want it; that you can change the software and use pieces of
|
|
||||||
it in new free programs; and that you are informed that you can do
|
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
|
||||||
rights. These restrictions translate to certain responsibilities for
|
|
||||||
you if you distribute copies of the library or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link other code with the library, you must provide
|
|
||||||
complete object files to the recipients, so that they can relink them
|
|
||||||
with the library after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
|
||||||
library, and (2) we offer you this license, which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
|
||||||
there is no warranty for the free library. Also, if the library is
|
|
||||||
modified by someone else and passed on, the recipients should know
|
|
||||||
that what they have is not the original version, so that the original
|
|
||||||
author's reputation will not be affected by problems that might be
|
|
||||||
introduced by others.
|
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
|
||||||
any free program. We wish to make sure that a company cannot
|
|
||||||
effectively restrict the users of a free program by obtaining a
|
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
|
||||||
any patent license obtained for a version of the library must be
|
|
||||||
consistent with the full freedom of use specified in this license.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
|
||||||
General Public License, applies to certain designated libraries, and
|
|
||||||
is quite different from the ordinary General Public License. We use
|
|
||||||
this license for certain libraries in order to permit linking those
|
|
||||||
libraries into non-free programs.
|
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
|
||||||
a shared library, the combination of the two is legally speaking a
|
|
||||||
combined work, a derivative of the original library. The ordinary
|
|
||||||
General Public License therefore permits such linking only if the
|
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
|
||||||
Public License permits more lax criteria for linking other code with
|
|
||||||
the library.
|
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
|
||||||
does Less to protect the user's freedom than the ordinary General
|
|
||||||
Public License. It also provides other free software developers Less
|
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
|
||||||
encourage the widest possible use of a certain library, so that it
|
|
||||||
becomes a de-facto standard. To achieve this, non-free programs must
|
|
||||||
be allowed to use the library. A more frequent case is that a free
|
|
||||||
library does the same job as widely used non-free libraries. In this
|
|
||||||
case, there is little to gain by limiting the free library to free
|
|
||||||
software only, so we use the Lesser General Public License.
|
|
||||||
|
|
||||||
In other cases, permission to use a particular library in non-free
|
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, whereas the latter must
|
|
||||||
be combined with the library in order to run.
|
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
|
||||||
program which contains a notice placed by the copyright holder or
|
|
||||||
other authorized party saying it may be distributed under the terms of
|
|
||||||
this Lesser General Public License (also called "this License").
|
|
||||||
Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, complete source code means
|
|
||||||
all the source code for all modules it contains, plus any associated
|
|
||||||
interface definition files, plus the scripts used to control
|
|
||||||
compilation and installation of the library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete source code as you receive it, in any medium, provided that
|
|
||||||
you conspicuously and appropriately publish on each copy an
|
|
||||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
|
||||||
all the notices that refer to this License and to the absence of any
|
|
||||||
warranty; and distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy,
|
|
||||||
and you may at your option offer warranty protection in exchange for a
|
|
||||||
fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Library, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote
|
|
||||||
it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you accompany
|
|
||||||
it with the complete corresponding machine-readable source code, which
|
|
||||||
must be distributed under the terms of Sections 1 and 2 above on a
|
|
||||||
medium customarily used for software interchange.
|
|
||||||
|
|
||||||
If distribution of object code is made by offering access to copy
|
|
||||||
from a designated place, then offering equivalent access to copy the
|
|
||||||
source code from the same place satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at least
|
|
||||||
three years, to give the same user the materials specified in
|
|
||||||
Subsection 6a, above, for a charge no more than the cost of
|
|
||||||
performing this distribution.
|
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the materials to be distributed need not include anything that is
|
|
||||||
normally distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies
|
|
||||||
the executable.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library is void, and will automatically terminate your
|
|
||||||
rights under this License. However, parties who have received copies,
|
|
||||||
or rights, from you under this License will not have their licenses
|
|
||||||
terminated so long as such parties remain in full compliance.
|
|
||||||
|
|
||||||
9. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
subject to these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties with
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Library.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply, and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding those
|
|
||||||
countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Lesser General Public License from time to time.
|
|
||||||
Such new versions will be similar in spirit to the present version,
|
|
||||||
but may differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Library
|
|
||||||
specifies a version number of this License which applies to it and
|
|
||||||
"any later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
write to the author to ask for permission. For software which is
|
|
||||||
copyrighted by the Free Software Foundation, write to the Free
|
|
||||||
Software Foundation; we sometimes make exceptions for this. Our
|
|
||||||
decision will be guided by the two goals of preserving the free status
|
|
||||||
of all derivatives of our free software and of promoting the sharing
|
|
||||||
and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
|
||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
|
||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
|
||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
|
||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
|
||||||
possible use to the public, we recommend making it free software that
|
|
||||||
everyone can redistribute and change. You can do so by permitting
|
|
||||||
redistribution under these terms (or, alternatively, under the terms
|
|
||||||
of the ordinary General Public License).
|
|
||||||
|
|
||||||
To apply these terms, attach the following notices to the library.
|
|
||||||
It is safest to attach them to the start of each source file to most
|
|
||||||
effectively convey the exclusion of warranty; and each file should
|
|
||||||
have at least the "copyright" line and a pointer to where the full
|
|
||||||
notice is found.
|
|
||||||
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or
|
|
||||||
your school, if any, to sign a "copyright disclaimer" for the library,
|
|
||||||
if necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
|
||||||
library `Frob' (a library for tweaking knobs) written by James
|
|
||||||
Random Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
That's all there is to it!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
pip
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
Metadata-Version: 2.1
|
|
||||||
Name: astroid
|
|
||||||
Version: 2.4.2
|
|
||||||
Summary: An abstract syntax tree for Python with inference support.
|
|
||||||
Home-page: https://github.com/PyCQA/astroid
|
|
||||||
Author: Python Code Quality Authority
|
|
||||||
Author-email: code-quality@python.org
|
|
||||||
License: LGPL
|
|
||||||
Platform: UNKNOWN
|
|
||||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
||||||
Classifier: Topic :: Software Development :: Quality Assurance
|
|
||||||
Classifier: Programming Language :: Python
|
|
||||||
Classifier: Programming Language :: Python :: 3
|
|
||||||
Classifier: Programming Language :: Python :: 3.5
|
|
||||||
Classifier: Programming Language :: Python :: 3.6
|
|
||||||
Classifier: Programming Language :: Python :: 3.7
|
|
||||||
Classifier: Programming Language :: Python :: 3.8
|
|
||||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
||||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
||||||
Requires-Python: >=3.5
|
|
||||||
Requires-Dist: lazy-object-proxy (==1.4.*)
|
|
||||||
Requires-Dist: six (~=1.12)
|
|
||||||
Requires-Dist: wrapt (~=1.11)
|
|
||||||
Requires-Dist: typed-ast (<1.5,>=1.4.0) ; implementation_name == "cpython" and python_version < "3.8"
|
|
||||||
|
|
||||||
Astroid
|
|
||||||
=======
|
|
||||||
|
|
||||||
.. image:: https://travis-ci.org/PyCQA/astroid.svg?branch=master
|
|
||||||
:target: https://travis-ci.org/PyCQA/astroid
|
|
||||||
|
|
||||||
.. image:: https://ci.appveyor.com/api/projects/status/co3u42kunguhbh6l/branch/master?svg=true
|
|
||||||
:alt: AppVeyor Build Status
|
|
||||||
:target: https://ci.appveyor.com/project/PCManticore/astroid
|
|
||||||
|
|
||||||
.. image:: https://coveralls.io/repos/github/PyCQA/astroid/badge.svg?branch=master
|
|
||||||
:target: https://coveralls.io/github/PyCQA/astroid?branch=master
|
|
||||||
|
|
||||||
.. 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
|
|
||||||
|
|
||||||
.. |tideliftlogo| image:: doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png
|
|
||||||
:width: 75
|
|
||||||
:height: 60
|
|
||||||
:alt: Tidelift
|
|
||||||
|
|
||||||
.. list-table::
|
|
||||||
:widths: 10 100
|
|
||||||
|
|
||||||
* - |tideliftlogo|
|
|
||||||
- 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, older versions of astroid will still supported until 2020.
|
|
||||||
|
|
||||||
Test
|
|
||||||
----
|
|
||||||
|
|
||||||
Tests are in the 'test' subdirectory. To launch the whole tests suite, you can use
|
|
||||||
either `tox` or `pytest`::
|
|
||||||
|
|
||||||
tox
|
|
||||||
pytest astroid
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
||||||
astroid-2.4.2.dist-info/COPYING,sha256=qxX9UmvY3Rip5368E5ZWv00z6X_HI4zRG_YOK5uGZsY,17987
|
|
||||||
astroid-2.4.2.dist-info/COPYING.LESSER,sha256=qb3eVhbs3R6YC0TzYGAO6Hg7H5m4zIOivrFjoKOQ6GE,26527
|
|
||||||
astroid-2.4.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
|
||||||
astroid-2.4.2.dist-info/METADATA,sha256=mWlOM8vl6thD_vA7Lzn2yKmQuaX8NukwS72gEpsGM0U,3915
|
|
||||||
astroid-2.4.2.dist-info/RECORD,,
|
|
||||||
astroid-2.4.2.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
|
||||||
astroid-2.4.2.dist-info/top_level.txt,sha256=HsdW4O2x7ZXRj6k-agi3RaQybGLobI3VSE-jt4vQUXM,8
|
|
||||||
astroid/__init__.py,sha256=zZF5EWBTfOtOcFd62WMbhLAtS2b_Fm-3JJW2AVUUMUI,5655
|
|
||||||
astroid/__pkginfo__.py,sha256=G6QlkatrWucF445cQW7Kb2ZSgBzf7TiKLPwqkP0CoQU,2329
|
|
||||||
astroid/__pycache__/__init__.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/__pkginfo__.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/_ast.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/arguments.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/as_string.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/bases.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/builder.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/context.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/decorators.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/exceptions.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/helpers.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/inference.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/manager.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/mixins.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/modutils.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/node_classes.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/nodes.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/objects.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/protocols.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/raw_building.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/rebuilder.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/scoped_nodes.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/test_utils.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/transforms.cpython-37.pyc,,
|
|
||||||
astroid/__pycache__/util.cpython-37.pyc,,
|
|
||||||
astroid/_ast.py,sha256=n1U2HblBNrMhsmrjF84HUfIgEZ3PyHyiJJOrOkgiUFk,3385
|
|
||||||
astroid/arguments.py,sha256=KJcZn7HeEhj2fZICr-9Pi7iueCNDZRQWh0T7O-qb-AE,12558
|
|
||||||
astroid/as_string.py,sha256=8bOZWsGG79TLmlzRzPtmHdanIAqQUFTKiYH873iMhOw,22821
|
|
||||||
astroid/bases.py,sha256=wL9C23mHFaj7vhMqM83DdsU6kfP488aEjoFWaO8p6Cg,19175
|
|
||||||
astroid/brain/__pycache__/brain_argparse.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_attrs.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_boto3.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_builtin_inference.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_collections.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_crypt.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_curses.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_dataclasses.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_dateutil.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_functools.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_gi.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_http.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_io.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_mechanize.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_namedtuple_enum.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_nose.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_core_umath.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_ndarray.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_numpy_utils.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_pytest.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_qt.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_random.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_re.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_responses.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_scipy_signal.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_six.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_ssl.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_subprocess.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_threading.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_typing.cpython-37.pyc,,
|
|
||||||
astroid/brain/__pycache__/brain_uuid.cpython-37.pyc,,
|
|
||||||
astroid/brain/brain_argparse.py,sha256=5XqcThekktCIWRlWAMs-R47wkbsOUSnQlsEbLEnRpsY,1041
|
|
||||||
astroid/brain/brain_attrs.py,sha256=k8zJqIXsIbQrncthrzyB5NtdPTktgVi9wG7nyl8xMzs,2208
|
|
||||||
astroid/brain/brain_boto3.py,sha256=nE8Cw_S_Gp___IszRDRkhEGS6WGrKcF_gTOs3GVxH9k,862
|
|
||||||
astroid/brain/brain_builtin_inference.py,sha256=F6_09yM2mmu_u3ad_f9Uumc-q0lDA2CY8v9-PYtUMmA,28793
|
|
||||||
astroid/brain/brain_collections.py,sha256=Uqi4VmpLDl0ndQa9x-5tIXRtVdtI6TlwR9KNHmOqLyw,2724
|
|
||||||
astroid/brain/brain_crypt.py,sha256=gA7Q4GVuAM4viuTGWM6SNTPQXv5Gr_mFapyKMTRcsJ0,875
|
|
||||||
astroid/brain/brain_curses.py,sha256=tDnlCP1bEvleqCMz856yua9mM5um1p_JendFhT4rBFk,3303
|
|
||||||
astroid/brain/brain_dataclasses.py,sha256=5WndOYSY0oi2v-Od6KdPte-FKt00LoNRH2riSB4S1os,1647
|
|
||||||
astroid/brain/brain_dateutil.py,sha256=GwDrgbaUkKbp3ImLAvuUtPuDBeK3lPh0bNI_Wphm2_8,801
|
|
||||||
astroid/brain/brain_fstrings.py,sha256=Jaf-G-wkLecwG4jfjjfR8MDKzgAjjn2mgrrWZQLOAd8,2126
|
|
||||||
astroid/brain/brain_functools.py,sha256=Nljy7o2vu16S2amFot4wdTI0U76Yafq-ujVPHOdGgCE,5481
|
|
||||||
astroid/brain/brain_gi.py,sha256=oraXhBWyCCxmPEAEvRboeTIho0--ORObvckni00_1wY,7554
|
|
||||||
astroid/brain/brain_hashlib.py,sha256=W2cS6-rixdBcre6lPWIuSOqPLCcVji5JBlImdPbV6Qo,2292
|
|
||||||
astroid/brain/brain_http.py,sha256=a_8eIACvZetnR2xI4ZARVMuB1WSjyyqM3rCl2DVltMo,10524
|
|
||||||
astroid/brain/brain_io.py,sha256=wEY3vvTeV23tYxFn8HHQeyjhb7-jqzwgwNI-kl2Yu-c,1476
|
|
||||||
astroid/brain/brain_mechanize.py,sha256=boZxoCxPGSpHC_RccO5U026hyXyhunXR55M9WM1lYTo,895
|
|
||||||
astroid/brain/brain_multiprocessing.py,sha256=9OswtRuVBj-KemJ0yp4prz8mrkJDzOzN6n13u2MgmwM,3096
|
|
||||||
astroid/brain/brain_namedtuple_enum.py,sha256=eZ8IaHPLLHBakywJ3q4Ogtd2Tk0gtNcAgYAloMAKTjM,15966
|
|
||||||
astroid/brain/brain_nose.py,sha256=PSPmme611h7fC8MKuVXbiGw0HZhdmIuoxM6yieZ1OOc,2217
|
|
||||||
astroid/brain/brain_numpy_core_fromnumeric.py,sha256=NxiHbcMyQQ3Gpx4KEA5eAmGrpjlPN5rfXjRLjHPOVkw,621
|
|
||||||
astroid/brain/brain_numpy_core_function_base.py,sha256=7i6Kge_PviqoWXhbeRgB581xwLo0dxvO54_5UB3ppig,1168
|
|
||||||
astroid/brain/brain_numpy_core_multiarray.py,sha256=vr-nBt3EF_z-UmHmcAlJhGorgDXPpQaYX8g4TWu_2Vw,4015
|
|
||||||
astroid/brain/brain_numpy_core_numeric.py,sha256=M0RXOym2YC-DaZfRqGNIpr6s-Oh1KHn1okGr3PtPl0k,1384
|
|
||||||
astroid/brain/brain_numpy_core_numerictypes.py,sha256=ltlZyQprEbVdUJpC_ERGyXyJsYwzFHx7zGYDLheIonA,8013
|
|
||||||
astroid/brain/brain_numpy_core_umath.py,sha256=je6K3ILMen2mgkZseHCOjOgnFV6SaNgAihEi6irhbRk,4436
|
|
||||||
astroid/brain/brain_numpy_ndarray.py,sha256=WZbRG7GgOWZ68sEr4JjZUnJHLfUc91xp2mucHeLMrnw,8463
|
|
||||||
astroid/brain/brain_numpy_random_mtrand.py,sha256=WRy_CStllgZN2B3Dw2qxXbY4SBrCzu-cdaK230VQHaE,3278
|
|
||||||
astroid/brain/brain_numpy_utils.py,sha256=ZYtCVmn1x6P7iwYFohdW3CCrvVT5BCNYe-7jKcz_25s,1875
|
|
||||||
astroid/brain/brain_pkg_resources.py,sha256=S_5UED1Zg8ObEJumRdpYGnjxZzemh_G_NFj3p5NGPfc,2262
|
|
||||||
astroid/brain/brain_pytest.py,sha256=RYp7StKnC22n4vFJkHH5h7DAFWtouIcg-ZCXQ8Oz3xk,2390
|
|
||||||
astroid/brain/brain_qt.py,sha256=m2s4YXFrnOynWDf9omHOBLVqFriBdGJAmvarJCxiffM,2536
|
|
||||||
astroid/brain/brain_random.py,sha256=2RZY-QEXMNWp7E6h0l0-ke-DtjKTOFlTdjiQZi3XdQc,2432
|
|
||||||
astroid/brain/brain_re.py,sha256=le7VJHUAf80HyE_aQCh7_8FyDVK6JwNWA--c9RaMVQ8,1128
|
|
||||||
astroid/brain/brain_responses.py,sha256=GIAGkwMEGEZ9bJHI9uBGs_UmUy3DRBtjI_j_8dLBVsc,1534
|
|
||||||
astroid/brain/brain_scipy_signal.py,sha256=IKNnGXzEH5FKhPHM2hv57pNdo1emThWwZ0ksckdsOeE,2255
|
|
||||||
astroid/brain/brain_six.py,sha256=79aws4au6ZQJuf-YhBT4R-9wuVOwg-u0T42aUhCswK0,6187
|
|
||||||
astroid/brain/brain_ssl.py,sha256=9dMCTQ0JsX2gpdmBkYO7BByw3zN23oXRL8Svo2S1V28,3722
|
|
||||||
astroid/brain/brain_subprocess.py,sha256=yp-HsE69uh7T7C1kZYciAdRMQ48aNT51lI032oDppDk,4688
|
|
||||||
astroid/brain/brain_threading.py,sha256=dY8YwZ-zrB30_CQFYWh4AK3qUVssakgwLVwunQ6yYkU,837
|
|
||||||
astroid/brain/brain_typing.py,sha256=iFw33beNCitCJjJNvccIY6SsFJcdKVDdl-56DxDioh0,2780
|
|
||||||
astroid/brain/brain_uuid.py,sha256=YzfiOXavu515cS1prsKGfY4-12g_KWT0Yr4-5ti0v74,569
|
|
||||||
astroid/builder.py,sha256=72JlHrXRF9sS5zh1mqXlRHGFg88Efc2rm9yRJKDIShA,16891
|
|
||||||
astroid/context.py,sha256=MpwiEzWZ39a4WyqYgbSmePL2nZLqALt1gjrvi3TP35U,5169
|
|
||||||
astroid/decorators.py,sha256=z_wTjsiMlu_ElHtYUUuxaB2F_s4G0Ks7bmtCZS3IQ_Q,4283
|
|
||||||
astroid/exceptions.py,sha256=GLiZo9BdWILJShO-il8ra-tPZqaODMAX987F--LWv2w,6891
|
|
||||||
astroid/helpers.py,sha256=3YoJeVLoS-66T_abDorUNHiP8m2R7-faNnpc5yPJhrc,9448
|
|
||||||
astroid/inference.py,sha256=UiKKPRYqb5JINQIw1lSdBniHhXjCohCGAqycp2GkVI4,34686
|
|
||||||
astroid/interpreter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
||||||
astroid/interpreter/__pycache__/__init__.cpython-37.pyc,,
|
|
||||||
astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc,,
|
|
||||||
astroid/interpreter/__pycache__/objectmodel.cpython-37.pyc,,
|
|
||||||
astroid/interpreter/_import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
||||||
astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc,,
|
|
||||||
astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc,,
|
|
||||||
astroid/interpreter/_import/__pycache__/util.cpython-37.pyc,,
|
|
||||||
astroid/interpreter/_import/spec.py,sha256=rZ9kX3I0xPo_pFAYWeOk2Xbi4ZIg_5bRsouZgxOXegA,11436
|
|
||||||
astroid/interpreter/_import/util.py,sha256=inubUz6F3_kaMFaeleKUW6E6wCMIPrhU882zvwEZ02I,255
|
|
||||||
astroid/interpreter/dunder_lookup.py,sha256=dP-AZU_aGPNt03b1ttrMglxzeU3NtgnG0MfpSLPH6sg,2155
|
|
||||||
astroid/interpreter/objectmodel.py,sha256=bbPIaamrqrx7WHtG5YNs9dbrlDC00GrJPxPGoSTsnqg,25792
|
|
||||||
astroid/manager.py,sha256=jmEm9uH00mPA2Y68s10xrPNbZaadv_2c-CWluB3SYoE,13701
|
|
||||||
astroid/mixins.py,sha256=F2rv2Ow7AU3YT_2jitVJik95ZWRVK6hpf8BrkkspzUY,5571
|
|
||||||
astroid/modutils.py,sha256=GBW5Z691eqf6VAnPsZzeQ0WYzrl-0GGTHkkZNb_9XRQ,23242
|
|
||||||
astroid/node_classes.py,sha256=cBRkZ_u8ZoRkiXznYWq1L3I7cO-P9nGowNCy8T7Qpzk,142740
|
|
||||||
astroid/nodes.py,sha256=WoyRe22GNVRc2TRHWOUlqdxCdOVD8GKOq9v1LpPhkr8,2978
|
|
||||||
astroid/objects.py,sha256=caKeQPBtrrfqa1q844vkehXwpdMzvph5YJdJJdbD_m8,11035
|
|
||||||
astroid/protocols.py,sha256=m1ZHvKvFQZSZp993na4f9s8V17kqNPRfH-XpQc8gJ7c,27396
|
|
||||||
astroid/raw_building.py,sha256=PI70y2mPQ7JURDVyNZ6deeBFkvjNNaOQBkuo0VPbvQ4,17340
|
|
||||||
astroid/rebuilder.py,sha256=xn82eWlxzGcDd2VACUnNNWCxArfV9HI8g67fUip0XFk,39411
|
|
||||||
astroid/scoped_nodes.py,sha256=fUrmTyltaLCr9-i8RdC2e5dPA9O8w946Mvvft8mgXdM,98203
|
|
||||||
astroid/test_utils.py,sha256=axGB3j6ZEaVspL1ZgPizKgWehNEREb58Z97U7mQ-GA8,2319
|
|
||||||
astroid/transforms.py,sha256=1npwJWcQUSIjcpcWd1pc-dJhtHOyiboQHsETAIQd5co,3377
|
|
||||||
astroid/util.py,sha256=jg5LnqbWSZTZP1KgpxGBuC6Lfwhn9Jb2T2TohXghmC0,4785
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
Wheel-Version: 1.0
|
|
||||||
Generator: bdist_wheel (0.34.2)
|
|
||||||
Root-Is-Purelib: true
|
|
||||||
Tag: py3-none-any
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
astroid
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
# Copyright (c) 2006-2013, 2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2014 Google, Inc.
|
|
||||||
# Copyright (c) 2014 Eevee (Alex Munroe) <amunroe@yelp.com>
|
|
||||||
# Copyright (c) 2015-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
|
|
||||||
# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
# Copyright (c) 2019 Nick Drozd <nicholasdrozd@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Python Abstract Syntax Tree New Generation
|
|
||||||
|
|
||||||
The aim of this module is to provide a common base representation of
|
|
||||||
python source code for projects such as pychecker, pyreverse,
|
|
||||||
pylint... Well, actually the development of this library is essentially
|
|
||||||
governed by pylint's needs.
|
|
||||||
|
|
||||||
It extends class defined in the python's _ast module with some
|
|
||||||
additional methods and attributes. Instance attributes are added by a
|
|
||||||
builder object, which can either generate extended ast (let's call
|
|
||||||
them astroid ;) by visiting an existent ast tree or by inspecting living
|
|
||||||
object. Methods are added by monkey patching ast classes.
|
|
||||||
|
|
||||||
Main modules are:
|
|
||||||
|
|
||||||
* nodes and scoped_nodes for more information about methods and
|
|
||||||
attributes added to different node classes
|
|
||||||
|
|
||||||
* the manager contains a high level object to get astroid trees from
|
|
||||||
source files and living objects. It maintains a cache of previously
|
|
||||||
constructed tree for quick access
|
|
||||||
|
|
||||||
* builder contains the class responsible to build astroid trees
|
|
||||||
"""
|
|
||||||
|
|
||||||
import enum
|
|
||||||
import itertools
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import wrapt
|
|
||||||
|
|
||||||
|
|
||||||
_Context = enum.Enum("Context", "Load Store Del")
|
|
||||||
Load = _Context.Load
|
|
||||||
Store = _Context.Store
|
|
||||||
Del = _Context.Del
|
|
||||||
del _Context
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=wrong-import-order,wrong-import-position
|
|
||||||
from .__pkginfo__ import version as __version__
|
|
||||||
|
|
||||||
# WARNING: internal imports order matters !
|
|
||||||
|
|
||||||
# pylint: disable=redefined-builtin
|
|
||||||
|
|
||||||
# make all exception classes accessible from astroid package
|
|
||||||
from astroid.exceptions import *
|
|
||||||
|
|
||||||
# make all node classes accessible from astroid package
|
|
||||||
from astroid.nodes import *
|
|
||||||
|
|
||||||
# trigger extra monkey-patching
|
|
||||||
from astroid import inference
|
|
||||||
|
|
||||||
# more stuff available
|
|
||||||
from astroid import raw_building
|
|
||||||
from astroid.bases import BaseInstance, Instance, BoundMethod, UnboundMethod
|
|
||||||
from astroid.node_classes import are_exclusive, unpack_infer
|
|
||||||
from astroid.scoped_nodes import builtin_lookup
|
|
||||||
from astroid.builder import parse, extract_node
|
|
||||||
from astroid.util import Uninferable
|
|
||||||
|
|
||||||
# make a manager instance (borg) accessible from astroid package
|
|
||||||
from astroid.manager import AstroidManager
|
|
||||||
|
|
||||||
MANAGER = AstroidManager()
|
|
||||||
del AstroidManager
|
|
||||||
|
|
||||||
# transform utilities (filters and decorator)
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=dangerous-default-value
|
|
||||||
@wrapt.decorator
|
|
||||||
def _inference_tip_cached(func, instance, args, kwargs, _cache={}):
|
|
||||||
"""Cache decorator used for inference tips"""
|
|
||||||
node = args[0]
|
|
||||||
try:
|
|
||||||
return iter(_cache[func, node])
|
|
||||||
except KeyError:
|
|
||||||
result = func(*args, **kwargs)
|
|
||||||
# Need to keep an iterator around
|
|
||||||
original, copy = itertools.tee(result)
|
|
||||||
_cache[func, node] = list(copy)
|
|
||||||
return original
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: enable=dangerous-default-value
|
|
||||||
|
|
||||||
|
|
||||||
def inference_tip(infer_function, raise_on_overwrite=False):
|
|
||||||
"""Given an instance specific inference function, return a function to be
|
|
||||||
given to MANAGER.register_transform to set this inference function.
|
|
||||||
|
|
||||||
:param bool raise_on_overwrite: Raise an `InferenceOverwriteError`
|
|
||||||
if the inference tip will overwrite another. Used for debugging
|
|
||||||
|
|
||||||
Typical usage
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
MANAGER.register_transform(Call, inference_tip(infer_named_tuple),
|
|
||||||
predicate)
|
|
||||||
|
|
||||||
.. Note::
|
|
||||||
|
|
||||||
Using an inference tip will override
|
|
||||||
any previously set inference tip for the given
|
|
||||||
node. Use a predicate in the transform to prevent
|
|
||||||
excess overwrites.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def transform(node, infer_function=infer_function):
|
|
||||||
if (
|
|
||||||
raise_on_overwrite
|
|
||||||
and node._explicit_inference is not None
|
|
||||||
and node._explicit_inference is not infer_function
|
|
||||||
):
|
|
||||||
raise InferenceOverwriteError(
|
|
||||||
"Inference already set to {existing_inference}. "
|
|
||||||
"Trying to overwrite with {new_inference} for {node}".format(
|
|
||||||
existing_inference=infer_function,
|
|
||||||
new_inference=node._explicit_inference,
|
|
||||||
node=node,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# pylint: disable=no-value-for-parameter
|
|
||||||
node._explicit_inference = _inference_tip_cached(infer_function)
|
|
||||||
return node
|
|
||||||
|
|
||||||
return transform
|
|
||||||
|
|
||||||
|
|
||||||
def register_module_extender(manager, module_name, get_extension_mod):
|
|
||||||
def transform(node):
|
|
||||||
extension_module = get_extension_mod()
|
|
||||||
for name, objs in extension_module.locals.items():
|
|
||||||
node.locals[name] = objs
|
|
||||||
for obj in objs:
|
|
||||||
if obj.parent is extension_module:
|
|
||||||
obj.parent = node
|
|
||||||
|
|
||||||
manager.register_transform(Module, transform, lambda n: n.name == module_name)
|
|
||||||
|
|
||||||
|
|
||||||
# load brain plugins
|
|
||||||
BRAIN_MODULES_DIR = os.path.join(os.path.dirname(__file__), "brain")
|
|
||||||
if BRAIN_MODULES_DIR not in sys.path:
|
|
||||||
# add it to the end of the list so user path take precedence
|
|
||||||
sys.path.append(BRAIN_MODULES_DIR)
|
|
||||||
# load modules in this directory
|
|
||||||
for module in os.listdir(BRAIN_MODULES_DIR):
|
|
||||||
if module.endswith(".py"):
|
|
||||||
__import__(module[:-3])
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2014-2019 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2014 Google, Inc.
|
|
||||||
# Copyright (c) 2015-2017 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
|
|
||||||
# Copyright (c) 2015 Radosław Ganczarek <radoslaw@ganczarek.in>
|
|
||||||
# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
|
|
||||||
# Copyright (c) 2017 Hugo <hugovk@users.noreply.github.com>
|
|
||||||
# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
|
|
||||||
# Copyright (c) 2017 Calen Pennington <cale@edx.org>
|
|
||||||
# Copyright (c) 2018 Ville Skyttä <ville.skytta@iki.fi>
|
|
||||||
# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
# Copyright (c) 2019 Uilian Ries <uilianries@gmail.com>
|
|
||||||
# Copyright (c) 2019 Thomas Hisch <t.hisch@gmail.com>
|
|
||||||
# Copyright (c) 2020 Michael <michael-k@users.noreply.github.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""astroid packaging information"""
|
|
||||||
|
|
||||||
version = "2.4.2"
|
|
||||||
numversion = tuple(int(elem) for elem in version.split(".") if elem.isdigit())
|
|
||||||
|
|
||||||
extras_require = {}
|
|
||||||
install_requires = [
|
|
||||||
"lazy_object_proxy==1.4.*",
|
|
||||||
"six~=1.12",
|
|
||||||
"wrapt~=1.11",
|
|
||||||
'typed-ast>=1.4.0,<1.5;implementation_name== "cpython" and python_version<"3.8"',
|
|
||||||
]
|
|
||||||
|
|
||||||
# pylint: disable=redefined-builtin; why license is a builtin anyway?
|
|
||||||
license = "LGPL"
|
|
||||||
|
|
||||||
author = "Python Code Quality Authority"
|
|
||||||
author_email = "code-quality@python.org"
|
|
||||||
mailinglist = "mailto://%s" % author_email
|
|
||||||
web = "https://github.com/PyCQA/astroid"
|
|
||||||
|
|
||||||
description = "An abstract syntax tree for Python with inference support."
|
|
||||||
|
|
||||||
classifiers = [
|
|
||||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
||||||
"Topic :: Software Development :: Quality Assurance",
|
|
||||||
"Programming Language :: Python",
|
|
||||||
"Programming Language :: Python :: 3",
|
|
||||||
"Programming Language :: Python :: 3.5",
|
|
||||||
"Programming Language :: Python :: 3.6",
|
|
||||||
"Programming Language :: Python :: 3.7",
|
|
||||||
"Programming Language :: Python :: 3.8",
|
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
|
||||||
"Programming Language :: Python :: Implementation :: PyPy",
|
|
||||||
]
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
import ast
|
|
||||||
from collections import namedtuple
|
|
||||||
from functools import partial
|
|
||||||
from typing import Optional
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
_ast_py3 = None
|
|
||||||
try:
|
|
||||||
import typed_ast.ast3 as _ast_py3
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
PY38 = sys.version_info[:2] >= (3, 8)
|
|
||||||
if PY38:
|
|
||||||
# On Python 3.8, typed_ast was merged back into `ast`
|
|
||||||
_ast_py3 = ast
|
|
||||||
|
|
||||||
|
|
||||||
FunctionType = namedtuple("FunctionType", ["argtypes", "returns"])
|
|
||||||
|
|
||||||
|
|
||||||
class ParserModule(
|
|
||||||
namedtuple(
|
|
||||||
"ParserModule",
|
|
||||||
[
|
|
||||||
"module",
|
|
||||||
"unary_op_classes",
|
|
||||||
"cmp_op_classes",
|
|
||||||
"bool_op_classes",
|
|
||||||
"bin_op_classes",
|
|
||||||
"context_classes",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
):
|
|
||||||
def parse(self, string: str, type_comments=True):
|
|
||||||
if self.module is _ast_py3:
|
|
||||||
if PY38:
|
|
||||||
parse_func = partial(self.module.parse, type_comments=type_comments)
|
|
||||||
else:
|
|
||||||
parse_func = partial(
|
|
||||||
self.module.parse, feature_version=sys.version_info.minor
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
parse_func = self.module.parse
|
|
||||||
return parse_func(string)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_function_type_comment(type_comment: str) -> Optional[FunctionType]:
|
|
||||||
"""Given a correct type comment, obtain a FunctionType object"""
|
|
||||||
if _ast_py3 is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
func_type = _ast_py3.parse(type_comment, "<type_comment>", "func_type")
|
|
||||||
return FunctionType(argtypes=func_type.argtypes, returns=func_type.returns)
|
|
||||||
|
|
||||||
|
|
||||||
def get_parser_module(type_comments=True) -> ParserModule:
|
|
||||||
if not type_comments:
|
|
||||||
parser_module = ast
|
|
||||||
else:
|
|
||||||
parser_module = _ast_py3
|
|
||||||
parser_module = parser_module or ast
|
|
||||||
|
|
||||||
unary_op_classes = _unary_operators_from_module(parser_module)
|
|
||||||
cmp_op_classes = _compare_operators_from_module(parser_module)
|
|
||||||
bool_op_classes = _bool_operators_from_module(parser_module)
|
|
||||||
bin_op_classes = _binary_operators_from_module(parser_module)
|
|
||||||
context_classes = _contexts_from_module(parser_module)
|
|
||||||
|
|
||||||
return ParserModule(
|
|
||||||
parser_module,
|
|
||||||
unary_op_classes,
|
|
||||||
cmp_op_classes,
|
|
||||||
bool_op_classes,
|
|
||||||
bin_op_classes,
|
|
||||||
context_classes,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _unary_operators_from_module(module):
|
|
||||||
return {module.UAdd: "+", module.USub: "-", module.Not: "not", module.Invert: "~"}
|
|
||||||
|
|
||||||
|
|
||||||
def _binary_operators_from_module(module):
|
|
||||||
binary_operators = {
|
|
||||||
module.Add: "+",
|
|
||||||
module.BitAnd: "&",
|
|
||||||
module.BitOr: "|",
|
|
||||||
module.BitXor: "^",
|
|
||||||
module.Div: "/",
|
|
||||||
module.FloorDiv: "//",
|
|
||||||
module.MatMult: "@",
|
|
||||||
module.Mod: "%",
|
|
||||||
module.Mult: "*",
|
|
||||||
module.Pow: "**",
|
|
||||||
module.Sub: "-",
|
|
||||||
module.LShift: "<<",
|
|
||||||
module.RShift: ">>",
|
|
||||||
}
|
|
||||||
return binary_operators
|
|
||||||
|
|
||||||
|
|
||||||
def _bool_operators_from_module(module):
|
|
||||||
return {module.And: "and", module.Or: "or"}
|
|
||||||
|
|
||||||
|
|
||||||
def _compare_operators_from_module(module):
|
|
||||||
return {
|
|
||||||
module.Eq: "==",
|
|
||||||
module.Gt: ">",
|
|
||||||
module.GtE: ">=",
|
|
||||||
module.In: "in",
|
|
||||||
module.Is: "is",
|
|
||||||
module.IsNot: "is not",
|
|
||||||
module.Lt: "<",
|
|
||||||
module.LtE: "<=",
|
|
||||||
module.NotEq: "!=",
|
|
||||||
module.NotIn: "not in",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _contexts_from_module(module):
|
|
||||||
return {
|
|
||||||
module.Load: astroid.Load,
|
|
||||||
module.Store: astroid.Store,
|
|
||||||
module.Del: astroid.Del,
|
|
||||||
module.Param: astroid.Store,
|
|
||||||
}
|
|
||||||
|
|
@ -1,300 +0,0 @@
|
||||||
# Copyright (c) 2015-2016, 2018-2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com>
|
|
||||||
# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
from astroid import bases
|
|
||||||
from astroid import context as contextmod
|
|
||||||
from astroid import exceptions
|
|
||||||
from astroid import nodes
|
|
||||||
from astroid import util
|
|
||||||
|
|
||||||
|
|
||||||
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, argument_context_map=None, context=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()
|
|
||||||
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 arg is not util.Uninferable
|
|
||||||
]
|
|
||||||
self.keyword_arguments = {
|
|
||||||
key: value
|
|
||||||
for key, value in self._unpacked_kwargs.items()
|
|
||||||
if value is not util.Uninferable
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_call(cls, call_node, context=None):
|
|
||||||
"""Get a CallSite object from the given Call node.
|
|
||||||
|
|
||||||
:param context:
|
|
||||||
An instance of :class:`astroid.context.Context` that will be used
|
|
||||||
to force a single inference path.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Determine the callcontext from the given `context` object if any.
|
|
||||||
context = context or contextmod.InferenceContext()
|
|
||||||
callcontext = contextmod.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):
|
|
||||||
"""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=None):
|
|
||||||
values = {}
|
|
||||||
context = context or contextmod.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 exceptions.InferenceError:
|
|
||||||
values[name] = util.Uninferable
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not isinstance(inferred, nodes.Dict):
|
|
||||||
# Not something we can work with.
|
|
||||||
values[name] = util.Uninferable
|
|
||||||
continue
|
|
||||||
|
|
||||||
for dict_key, dict_value in inferred.items:
|
|
||||||
try:
|
|
||||||
dict_key = next(dict_key.infer(context=context))
|
|
||||||
except exceptions.InferenceError:
|
|
||||||
values[name] = util.Uninferable
|
|
||||||
continue
|
|
||||||
if not isinstance(dict_key, nodes.Const):
|
|
||||||
values[name] = util.Uninferable
|
|
||||||
continue
|
|
||||||
if not isinstance(dict_key.value, str):
|
|
||||||
values[name] = util.Uninferable
|
|
||||||
continue
|
|
||||||
if dict_key.value in values:
|
|
||||||
# The name is already in the dictionary
|
|
||||||
values[dict_key.value] = util.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=None):
|
|
||||||
values = []
|
|
||||||
context = context or contextmod.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 exceptions.InferenceError:
|
|
||||||
values.append(util.Uninferable)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if inferred is util.Uninferable:
|
|
||||||
values.append(util.Uninferable)
|
|
||||||
continue
|
|
||||||
if not hasattr(inferred, "elts"):
|
|
||||||
values.append(util.Uninferable)
|
|
||||||
continue
|
|
||||||
values.extend(inferred.elts)
|
|
||||||
else:
|
|
||||||
values.append(arg)
|
|
||||||
return values
|
|
||||||
|
|
||||||
def infer_argument(self, funcnode, name, context):
|
|
||||||
"""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 exceptions.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:
|
|
||||||
raise exceptions.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:
|
|
||||||
# 2. first argument of instance/class method
|
|
||||||
if argindex == 0 and funcnode.type in ("method", "classmethod"):
|
|
||||||
if context.boundnode is not None:
|
|
||||||
boundnode = context.boundnode
|
|
||||||
else:
|
|
||||||
# XXX can do better ?
|
|
||||||
boundnode = funcnode.parent.frame()
|
|
||||||
|
|
||||||
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, bases.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"):
|
|
||||||
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 exceptions.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 exceptions.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 exceptions.NoDefault:
|
|
||||||
pass
|
|
||||||
raise exceptions.InferenceError(
|
|
||||||
"No value found for argument {name} to " "{func!r}",
|
|
||||||
call_site=self,
|
|
||||||
func=funcnode,
|
|
||||||
arg=name,
|
|
||||||
context=context,
|
|
||||||
)
|
|
||||||
|
|
@ -1,631 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2010 Daniel Harding <dharding@gmail.com>
|
|
||||||
# Copyright (c) 2013-2016, 2018-2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2013-2014 Google, Inc.
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2016 Jared Garst <jgarst@users.noreply.github.com>
|
|
||||||
# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net>
|
|
||||||
# Copyright (c) 2017, 2019 Łukasz Rogalski <rogalski.91@gmail.com>
|
|
||||||
# Copyright (c) 2017 rr- <rr-@sakuya.pl>
|
|
||||||
# Copyright (c) 2018 Serhiy Storchaka <storchaka@gmail.com>
|
|
||||||
# Copyright (c) 2018 Ville Skyttä <ville.skytta@iki.fi>
|
|
||||||
# Copyright (c) 2018 brendanator <brendan.maginnis@gmail.com>
|
|
||||||
# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com>
|
|
||||||
# Copyright (c) 2019 Alex Hall <alex.mojaki@gmail.com>
|
|
||||||
# Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""This module renders Astroid nodes as string:
|
|
||||||
|
|
||||||
* :func:`to_code` function return equivalent (hopefully valid) python string
|
|
||||||
|
|
||||||
* :func:`dump` function return an internal representation of nodes found
|
|
||||||
in the tree, useful for debugging or understanding the tree structure
|
|
||||||
"""
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
|
|
||||||
DOC_NEWLINE = "\0"
|
|
||||||
|
|
||||||
|
|
||||||
class AsStringVisitor:
|
|
||||||
"""Visitor to render an Astroid node as a valid python code string"""
|
|
||||||
|
|
||||||
def __init__(self, indent):
|
|
||||||
self.indent = indent
|
|
||||||
|
|
||||||
def __call__(self, node):
|
|
||||||
"""Makes this visitor behave as a simple function"""
|
|
||||||
return node.accept(self).replace(DOC_NEWLINE, "\n")
|
|
||||||
|
|
||||||
def _docs_dedent(self, doc):
|
|
||||||
"""Stop newlines in docs being indented by self._stmt_list"""
|
|
||||||
return '\n%s"""%s"""' % (self.indent, doc.replace("\n", DOC_NEWLINE))
|
|
||||||
|
|
||||||
def _stmt_list(self, stmts, indent=True):
|
|
||||||
"""return a list of nodes to string"""
|
|
||||||
stmts = "\n".join(nstr for nstr in [n.accept(self) for n in stmts] if nstr)
|
|
||||||
if indent:
|
|
||||||
return self.indent + stmts.replace("\n", "\n" + self.indent)
|
|
||||||
|
|
||||||
return stmts
|
|
||||||
|
|
||||||
def _precedence_parens(self, node, child, is_left=True):
|
|
||||||
"""Wrap child in parens only if required to keep same semantics"""
|
|
||||||
if self._should_wrap(node, child, is_left):
|
|
||||||
return "(%s)" % child.accept(self)
|
|
||||||
|
|
||||||
return child.accept(self)
|
|
||||||
|
|
||||||
def _should_wrap(self, node, child, is_left):
|
|
||||||
"""Wrap child if:
|
|
||||||
- it has lower precedence
|
|
||||||
- same precedence with position opposite to associativity direction
|
|
||||||
"""
|
|
||||||
node_precedence = node.op_precedence()
|
|
||||||
child_precedence = child.op_precedence()
|
|
||||||
|
|
||||||
if node_precedence > child_precedence:
|
|
||||||
# 3 * (4 + 5)
|
|
||||||
return True
|
|
||||||
|
|
||||||
if (
|
|
||||||
node_precedence == child_precedence
|
|
||||||
and is_left != node.op_left_associative()
|
|
||||||
):
|
|
||||||
# 3 - (4 - 5)
|
|
||||||
# (2**3)**4
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
## visit_<node> methods ###########################################
|
|
||||||
|
|
||||||
def visit_await(self, node):
|
|
||||||
return "await %s" % node.value.accept(self)
|
|
||||||
|
|
||||||
def visit_asyncwith(self, node):
|
|
||||||
return "async %s" % self.visit_with(node)
|
|
||||||
|
|
||||||
def visit_asyncfor(self, node):
|
|
||||||
return "async %s" % self.visit_for(node)
|
|
||||||
|
|
||||||
def visit_arguments(self, node):
|
|
||||||
"""return an astroid.Function node as string"""
|
|
||||||
return node.format_args()
|
|
||||||
|
|
||||||
def visit_assignattr(self, node):
|
|
||||||
"""return an astroid.AssAttr node as string"""
|
|
||||||
return self.visit_attribute(node)
|
|
||||||
|
|
||||||
def visit_assert(self, node):
|
|
||||||
"""return an astroid.Assert node as string"""
|
|
||||||
if node.fail:
|
|
||||||
return "assert %s, %s" % (node.test.accept(self), node.fail.accept(self))
|
|
||||||
return "assert %s" % node.test.accept(self)
|
|
||||||
|
|
||||||
def visit_assignname(self, node):
|
|
||||||
"""return an astroid.AssName node as string"""
|
|
||||||
return node.name
|
|
||||||
|
|
||||||
def visit_assign(self, node):
|
|
||||||
"""return an astroid.Assign node as string"""
|
|
||||||
lhs = " = ".join(n.accept(self) for n in node.targets)
|
|
||||||
return "%s = %s" % (lhs, node.value.accept(self))
|
|
||||||
|
|
||||||
def visit_augassign(self, node):
|
|
||||||
"""return an astroid.AugAssign node as string"""
|
|
||||||
return "%s %s %s" % (node.target.accept(self), node.op, node.value.accept(self))
|
|
||||||
|
|
||||||
def visit_annassign(self, node):
|
|
||||||
"""Return an astroid.AugAssign node as string"""
|
|
||||||
|
|
||||||
target = node.target.accept(self)
|
|
||||||
annotation = node.annotation.accept(self)
|
|
||||||
if node.value is None:
|
|
||||||
return "%s: %s" % (target, annotation)
|
|
||||||
return "%s: %s = %s" % (target, annotation, node.value.accept(self))
|
|
||||||
|
|
||||||
def visit_repr(self, node):
|
|
||||||
"""return an astroid.Repr node as string"""
|
|
||||||
return "`%s`" % node.value.accept(self)
|
|
||||||
|
|
||||||
def visit_binop(self, node):
|
|
||||||
"""return an astroid.BinOp node as string"""
|
|
||||||
left = self._precedence_parens(node, node.left)
|
|
||||||
right = self._precedence_parens(node, node.right, is_left=False)
|
|
||||||
if node.op == "**":
|
|
||||||
return "%s%s%s" % (left, node.op, right)
|
|
||||||
|
|
||||||
return "%s %s %s" % (left, node.op, right)
|
|
||||||
|
|
||||||
def visit_boolop(self, node):
|
|
||||||
"""return an astroid.BoolOp node as string"""
|
|
||||||
values = ["%s" % self._precedence_parens(node, n) for n in node.values]
|
|
||||||
return (" %s " % node.op).join(values)
|
|
||||||
|
|
||||||
def visit_break(self, node):
|
|
||||||
"""return an astroid.Break node as string"""
|
|
||||||
return "break"
|
|
||||||
|
|
||||||
def visit_call(self, node):
|
|
||||||
"""return an astroid.Call node as string"""
|
|
||||||
expr_str = self._precedence_parens(node, node.func)
|
|
||||||
args = [arg.accept(self) for arg in node.args]
|
|
||||||
if node.keywords:
|
|
||||||
keywords = [kwarg.accept(self) for kwarg in node.keywords]
|
|
||||||
else:
|
|
||||||
keywords = []
|
|
||||||
|
|
||||||
args.extend(keywords)
|
|
||||||
return "%s(%s)" % (expr_str, ", ".join(args))
|
|
||||||
|
|
||||||
def visit_classdef(self, node):
|
|
||||||
"""return an astroid.ClassDef node as string"""
|
|
||||||
decorate = node.decorators.accept(self) if node.decorators else ""
|
|
||||||
args = [n.accept(self) for n in node.bases]
|
|
||||||
if node._metaclass and not node.has_metaclass_hack():
|
|
||||||
args.append("metaclass=" + node._metaclass.accept(self))
|
|
||||||
args += [n.accept(self) for n in node.keywords]
|
|
||||||
args = "(%s)" % ", ".join(args) if args else ""
|
|
||||||
docs = self._docs_dedent(node.doc) if node.doc else ""
|
|
||||||
return "\n\n%sclass %s%s:%s\n%s\n" % (
|
|
||||||
decorate,
|
|
||||||
node.name,
|
|
||||||
args,
|
|
||||||
docs,
|
|
||||||
self._stmt_list(node.body),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_compare(self, node):
|
|
||||||
"""return an astroid.Compare node as string"""
|
|
||||||
rhs_str = " ".join(
|
|
||||||
[
|
|
||||||
"%s %s" % (op, self._precedence_parens(node, expr, is_left=False))
|
|
||||||
for op, expr in node.ops
|
|
||||||
]
|
|
||||||
)
|
|
||||||
return "%s %s" % (self._precedence_parens(node, node.left), rhs_str)
|
|
||||||
|
|
||||||
def visit_comprehension(self, node):
|
|
||||||
"""return an astroid.Comprehension node as string"""
|
|
||||||
ifs = "".join(" if %s" % n.accept(self) for n in node.ifs)
|
|
||||||
generated = "for %s in %s%s" % (
|
|
||||||
node.target.accept(self),
|
|
||||||
node.iter.accept(self),
|
|
||||||
ifs,
|
|
||||||
)
|
|
||||||
return "%s%s" % ("async " if node.is_async else "", generated)
|
|
||||||
|
|
||||||
def visit_const(self, node):
|
|
||||||
"""return an astroid.Const node as string"""
|
|
||||||
if node.value is Ellipsis:
|
|
||||||
return "..."
|
|
||||||
return repr(node.value)
|
|
||||||
|
|
||||||
def visit_continue(self, node):
|
|
||||||
"""return an astroid.Continue node as string"""
|
|
||||||
return "continue"
|
|
||||||
|
|
||||||
def visit_delete(self, node): # XXX check if correct
|
|
||||||
"""return an astroid.Delete node as string"""
|
|
||||||
return "del %s" % ", ".join(child.accept(self) for child in node.targets)
|
|
||||||
|
|
||||||
def visit_delattr(self, node):
|
|
||||||
"""return an astroid.DelAttr node as string"""
|
|
||||||
return self.visit_attribute(node)
|
|
||||||
|
|
||||||
def visit_delname(self, node):
|
|
||||||
"""return an astroid.DelName node as string"""
|
|
||||||
return node.name
|
|
||||||
|
|
||||||
def visit_decorators(self, node):
|
|
||||||
"""return an astroid.Decorators node as string"""
|
|
||||||
return "@%s\n" % "\n@".join(item.accept(self) for item in node.nodes)
|
|
||||||
|
|
||||||
def visit_dict(self, node):
|
|
||||||
"""return an astroid.Dict node as string"""
|
|
||||||
return "{%s}" % ", ".join(self._visit_dict(node))
|
|
||||||
|
|
||||||
def _visit_dict(self, node):
|
|
||||||
for key, value in node.items:
|
|
||||||
key = key.accept(self)
|
|
||||||
value = value.accept(self)
|
|
||||||
if key == "**":
|
|
||||||
# It can only be a DictUnpack node.
|
|
||||||
yield key + value
|
|
||||||
else:
|
|
||||||
yield "%s: %s" % (key, value)
|
|
||||||
|
|
||||||
def visit_dictunpack(self, node):
|
|
||||||
return "**"
|
|
||||||
|
|
||||||
def visit_dictcomp(self, node):
|
|
||||||
"""return an astroid.DictComp node as string"""
|
|
||||||
return "{%s: %s %s}" % (
|
|
||||||
node.key.accept(self),
|
|
||||||
node.value.accept(self),
|
|
||||||
" ".join(n.accept(self) for n in node.generators),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_expr(self, node):
|
|
||||||
"""return an astroid.Discard node as string"""
|
|
||||||
return node.value.accept(self)
|
|
||||||
|
|
||||||
def visit_emptynode(self, node):
|
|
||||||
"""dummy method for visiting an Empty node"""
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def visit_excepthandler(self, node):
|
|
||||||
if node.type:
|
|
||||||
if node.name:
|
|
||||||
excs = "except %s as %s" % (
|
|
||||||
node.type.accept(self),
|
|
||||||
node.name.accept(self),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
excs = "except %s" % node.type.accept(self)
|
|
||||||
else:
|
|
||||||
excs = "except"
|
|
||||||
return "%s:\n%s" % (excs, self._stmt_list(node.body))
|
|
||||||
|
|
||||||
def visit_ellipsis(self, node):
|
|
||||||
"""return an astroid.Ellipsis node as string"""
|
|
||||||
return "..."
|
|
||||||
|
|
||||||
def visit_empty(self, node):
|
|
||||||
"""return an Empty node as string"""
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def visit_exec(self, node):
|
|
||||||
"""return an astroid.Exec node as string"""
|
|
||||||
if node.locals:
|
|
||||||
return "exec %s in %s, %s" % (
|
|
||||||
node.expr.accept(self),
|
|
||||||
node.locals.accept(self),
|
|
||||||
node.globals.accept(self),
|
|
||||||
)
|
|
||||||
if node.globals:
|
|
||||||
return "exec %s in %s" % (node.expr.accept(self), node.globals.accept(self))
|
|
||||||
return "exec %s" % node.expr.accept(self)
|
|
||||||
|
|
||||||
def visit_extslice(self, node):
|
|
||||||
"""return an astroid.ExtSlice node as string"""
|
|
||||||
return ", ".join(dim.accept(self) for dim in node.dims)
|
|
||||||
|
|
||||||
def visit_for(self, node):
|
|
||||||
"""return an astroid.For node as string"""
|
|
||||||
fors = "for %s in %s:\n%s" % (
|
|
||||||
node.target.accept(self),
|
|
||||||
node.iter.accept(self),
|
|
||||||
self._stmt_list(node.body),
|
|
||||||
)
|
|
||||||
if node.orelse:
|
|
||||||
fors = "%s\nelse:\n%s" % (fors, self._stmt_list(node.orelse))
|
|
||||||
return fors
|
|
||||||
|
|
||||||
def visit_importfrom(self, node):
|
|
||||||
"""return an astroid.ImportFrom node as string"""
|
|
||||||
return "from %s import %s" % (
|
|
||||||
"." * (node.level or 0) + node.modname,
|
|
||||||
_import_string(node.names),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_joinedstr(self, node):
|
|
||||||
string = "".join(
|
|
||||||
# Use repr on the string literal parts
|
|
||||||
# to get proper escapes, e.g. \n, \\, \"
|
|
||||||
# But strip the quotes off the ends
|
|
||||||
# (they will always be one character: ' or ")
|
|
||||||
repr(value.value)[1:-1]
|
|
||||||
# Literal braces must be doubled to escape them
|
|
||||||
.replace("{", "{{").replace("}", "}}")
|
|
||||||
# Each value in values is either a string literal (Const)
|
|
||||||
# or a FormattedValue
|
|
||||||
if type(value).__name__ == "Const" else value.accept(self)
|
|
||||||
for value in node.values
|
|
||||||
)
|
|
||||||
|
|
||||||
# Try to find surrounding quotes that don't appear at all in the string.
|
|
||||||
# Because the formatted values inside {} can't contain backslash (\)
|
|
||||||
# using a triple quote is sometimes necessary
|
|
||||||
for quote in ["'", '"', '"""', "'''"]:
|
|
||||||
if quote not in string:
|
|
||||||
break
|
|
||||||
|
|
||||||
return "f" + quote + string + quote
|
|
||||||
|
|
||||||
def visit_formattedvalue(self, node):
|
|
||||||
result = node.value.accept(self)
|
|
||||||
if node.conversion and node.conversion >= 0:
|
|
||||||
# e.g. if node.conversion == 114: result += "!r"
|
|
||||||
result += "!" + chr(node.conversion)
|
|
||||||
if node.format_spec:
|
|
||||||
# The format spec is itself a JoinedString, i.e. an f-string
|
|
||||||
# We strip the f and quotes of the ends
|
|
||||||
result += ":" + node.format_spec.accept(self)[2:-1]
|
|
||||||
return "{%s}" % result
|
|
||||||
|
|
||||||
def handle_functiondef(self, node, keyword):
|
|
||||||
"""return a (possibly async) function definition node as string"""
|
|
||||||
decorate = node.decorators.accept(self) if node.decorators else ""
|
|
||||||
docs = self._docs_dedent(node.doc) if node.doc else ""
|
|
||||||
trailer = ":"
|
|
||||||
if node.returns:
|
|
||||||
return_annotation = " -> " + node.returns.as_string()
|
|
||||||
trailer = return_annotation + ":"
|
|
||||||
def_format = "\n%s%s %s(%s)%s%s\n%s"
|
|
||||||
return def_format % (
|
|
||||||
decorate,
|
|
||||||
keyword,
|
|
||||||
node.name,
|
|
||||||
node.args.accept(self),
|
|
||||||
trailer,
|
|
||||||
docs,
|
|
||||||
self._stmt_list(node.body),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_functiondef(self, node):
|
|
||||||
"""return an astroid.FunctionDef node as string"""
|
|
||||||
return self.handle_functiondef(node, "def")
|
|
||||||
|
|
||||||
def visit_asyncfunctiondef(self, node):
|
|
||||||
"""return an astroid.AsyncFunction node as string"""
|
|
||||||
return self.handle_functiondef(node, "async def")
|
|
||||||
|
|
||||||
def visit_generatorexp(self, node):
|
|
||||||
"""return an astroid.GeneratorExp node as string"""
|
|
||||||
return "(%s %s)" % (
|
|
||||||
node.elt.accept(self),
|
|
||||||
" ".join(n.accept(self) for n in node.generators),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_attribute(self, node):
|
|
||||||
"""return an astroid.Getattr node as string"""
|
|
||||||
left = self._precedence_parens(node, node.expr)
|
|
||||||
if left.isdigit():
|
|
||||||
left = "(%s)" % left
|
|
||||||
return "%s.%s" % (left, node.attrname)
|
|
||||||
|
|
||||||
def visit_global(self, node):
|
|
||||||
"""return an astroid.Global node as string"""
|
|
||||||
return "global %s" % ", ".join(node.names)
|
|
||||||
|
|
||||||
def visit_if(self, node):
|
|
||||||
"""return an astroid.If node as string"""
|
|
||||||
ifs = ["if %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body))]
|
|
||||||
if node.has_elif_block():
|
|
||||||
ifs.append("el%s" % self._stmt_list(node.orelse, indent=False))
|
|
||||||
elif node.orelse:
|
|
||||||
ifs.append("else:\n%s" % self._stmt_list(node.orelse))
|
|
||||||
return "\n".join(ifs)
|
|
||||||
|
|
||||||
def visit_ifexp(self, node):
|
|
||||||
"""return an astroid.IfExp node as string"""
|
|
||||||
return "%s if %s else %s" % (
|
|
||||||
self._precedence_parens(node, node.body, is_left=True),
|
|
||||||
self._precedence_parens(node, node.test, is_left=True),
|
|
||||||
self._precedence_parens(node, node.orelse, is_left=False),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_import(self, node):
|
|
||||||
"""return an astroid.Import node as string"""
|
|
||||||
return "import %s" % _import_string(node.names)
|
|
||||||
|
|
||||||
def visit_keyword(self, node):
|
|
||||||
"""return an astroid.Keyword node as string"""
|
|
||||||
if node.arg is None:
|
|
||||||
return "**%s" % node.value.accept(self)
|
|
||||||
return "%s=%s" % (node.arg, node.value.accept(self))
|
|
||||||
|
|
||||||
def visit_lambda(self, node):
|
|
||||||
"""return an astroid.Lambda node as string"""
|
|
||||||
args = node.args.accept(self)
|
|
||||||
body = node.body.accept(self)
|
|
||||||
if args:
|
|
||||||
return "lambda %s: %s" % (args, body)
|
|
||||||
|
|
||||||
return "lambda: %s" % body
|
|
||||||
|
|
||||||
def visit_list(self, node):
|
|
||||||
"""return an astroid.List node as string"""
|
|
||||||
return "[%s]" % ", ".join(child.accept(self) for child in node.elts)
|
|
||||||
|
|
||||||
def visit_listcomp(self, node):
|
|
||||||
"""return an astroid.ListComp node as string"""
|
|
||||||
return "[%s %s]" % (
|
|
||||||
node.elt.accept(self),
|
|
||||||
" ".join(n.accept(self) for n in node.generators),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_module(self, node):
|
|
||||||
"""return an astroid.Module node as string"""
|
|
||||||
docs = '"""%s"""\n\n' % node.doc if node.doc else ""
|
|
||||||
return docs + "\n".join(n.accept(self) for n in node.body) + "\n\n"
|
|
||||||
|
|
||||||
def visit_name(self, node):
|
|
||||||
"""return an astroid.Name node as string"""
|
|
||||||
return node.name
|
|
||||||
|
|
||||||
def visit_namedexpr(self, node):
|
|
||||||
"""Return an assignment expression node as string"""
|
|
||||||
target = node.target.accept(self)
|
|
||||||
value = node.value.accept(self)
|
|
||||||
return "%s := %s" % (target, value)
|
|
||||||
|
|
||||||
def visit_nonlocal(self, node):
|
|
||||||
"""return an astroid.Nonlocal node as string"""
|
|
||||||
return "nonlocal %s" % ", ".join(node.names)
|
|
||||||
|
|
||||||
def visit_pass(self, node):
|
|
||||||
"""return an astroid.Pass node as string"""
|
|
||||||
return "pass"
|
|
||||||
|
|
||||||
def visit_print(self, node):
|
|
||||||
"""return an astroid.Print node as string"""
|
|
||||||
nodes = ", ".join(n.accept(self) for n in node.values)
|
|
||||||
if not node.nl:
|
|
||||||
nodes = "%s," % nodes
|
|
||||||
if node.dest:
|
|
||||||
return "print >> %s, %s" % (node.dest.accept(self), nodes)
|
|
||||||
return "print %s" % nodes
|
|
||||||
|
|
||||||
def visit_raise(self, node):
|
|
||||||
"""return an astroid.Raise node as string"""
|
|
||||||
if node.exc:
|
|
||||||
if node.cause:
|
|
||||||
return "raise %s from %s" % (
|
|
||||||
node.exc.accept(self),
|
|
||||||
node.cause.accept(self),
|
|
||||||
)
|
|
||||||
return "raise %s" % node.exc.accept(self)
|
|
||||||
return "raise"
|
|
||||||
|
|
||||||
def visit_return(self, node):
|
|
||||||
"""return an astroid.Return node as string"""
|
|
||||||
if node.is_tuple_return() and len(node.value.elts) > 1:
|
|
||||||
elts = [child.accept(self) for child in node.value.elts]
|
|
||||||
return "return %s" % ", ".join(elts)
|
|
||||||
|
|
||||||
if node.value:
|
|
||||||
return "return %s" % node.value.accept(self)
|
|
||||||
|
|
||||||
return "return"
|
|
||||||
|
|
||||||
def visit_index(self, node):
|
|
||||||
"""return an astroid.Index node as string"""
|
|
||||||
return node.value.accept(self)
|
|
||||||
|
|
||||||
def visit_set(self, node):
|
|
||||||
"""return an astroid.Set node as string"""
|
|
||||||
return "{%s}" % ", ".join(child.accept(self) for child in node.elts)
|
|
||||||
|
|
||||||
def visit_setcomp(self, node):
|
|
||||||
"""return an astroid.SetComp node as string"""
|
|
||||||
return "{%s %s}" % (
|
|
||||||
node.elt.accept(self),
|
|
||||||
" ".join(n.accept(self) for n in node.generators),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_slice(self, node):
|
|
||||||
"""return an astroid.Slice node as string"""
|
|
||||||
lower = node.lower.accept(self) if node.lower else ""
|
|
||||||
upper = node.upper.accept(self) if node.upper else ""
|
|
||||||
step = node.step.accept(self) if node.step else ""
|
|
||||||
if step:
|
|
||||||
return "%s:%s:%s" % (lower, upper, step)
|
|
||||||
return "%s:%s" % (lower, upper)
|
|
||||||
|
|
||||||
def visit_subscript(self, node):
|
|
||||||
"""return an astroid.Subscript node as string"""
|
|
||||||
idx = node.slice
|
|
||||||
if idx.__class__.__name__.lower() == "index":
|
|
||||||
idx = idx.value
|
|
||||||
idxstr = idx.accept(self)
|
|
||||||
if idx.__class__.__name__.lower() == "tuple" and idx.elts:
|
|
||||||
# Remove parenthesis in tuple and extended slice.
|
|
||||||
# a[(::1, 1:)] is not valid syntax.
|
|
||||||
idxstr = idxstr[1:-1]
|
|
||||||
return "%s[%s]" % (self._precedence_parens(node, node.value), idxstr)
|
|
||||||
|
|
||||||
def visit_tryexcept(self, node):
|
|
||||||
"""return an astroid.TryExcept node as string"""
|
|
||||||
trys = ["try:\n%s" % self._stmt_list(node.body)]
|
|
||||||
for handler in node.handlers:
|
|
||||||
trys.append(handler.accept(self))
|
|
||||||
if node.orelse:
|
|
||||||
trys.append("else:\n%s" % self._stmt_list(node.orelse))
|
|
||||||
return "\n".join(trys)
|
|
||||||
|
|
||||||
def visit_tryfinally(self, node):
|
|
||||||
"""return an astroid.TryFinally node as string"""
|
|
||||||
return "try:\n%s\nfinally:\n%s" % (
|
|
||||||
self._stmt_list(node.body),
|
|
||||||
self._stmt_list(node.finalbody),
|
|
||||||
)
|
|
||||||
|
|
||||||
def visit_tuple(self, node):
|
|
||||||
"""return an astroid.Tuple node as string"""
|
|
||||||
if len(node.elts) == 1:
|
|
||||||
return "(%s, )" % node.elts[0].accept(self)
|
|
||||||
return "(%s)" % ", ".join(child.accept(self) for child in node.elts)
|
|
||||||
|
|
||||||
def visit_unaryop(self, node):
|
|
||||||
"""return an astroid.UnaryOp node as string"""
|
|
||||||
if node.op == "not":
|
|
||||||
operator = "not "
|
|
||||||
else:
|
|
||||||
operator = node.op
|
|
||||||
return "%s%s" % (operator, self._precedence_parens(node, node.operand))
|
|
||||||
|
|
||||||
def visit_while(self, node):
|
|
||||||
"""return an astroid.While node as string"""
|
|
||||||
whiles = "while %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body))
|
|
||||||
if node.orelse:
|
|
||||||
whiles = "%s\nelse:\n%s" % (whiles, self._stmt_list(node.orelse))
|
|
||||||
return whiles
|
|
||||||
|
|
||||||
def visit_with(self, node): # 'with' without 'as' is possible
|
|
||||||
"""return an astroid.With node as string"""
|
|
||||||
items = ", ".join(
|
|
||||||
("%s" % expr.accept(self)) + (vars and " as %s" % (vars.accept(self)) or "")
|
|
||||||
for expr, vars in node.items
|
|
||||||
)
|
|
||||||
return "with %s:\n%s" % (items, self._stmt_list(node.body))
|
|
||||||
|
|
||||||
def visit_yield(self, node):
|
|
||||||
"""yield an ast.Yield node as string"""
|
|
||||||
yi_val = (" " + node.value.accept(self)) if node.value else ""
|
|
||||||
expr = "yield" + yi_val
|
|
||||||
if node.parent.is_statement:
|
|
||||||
return expr
|
|
||||||
|
|
||||||
return "(%s)" % (expr,)
|
|
||||||
|
|
||||||
def visit_yieldfrom(self, node):
|
|
||||||
""" Return an astroid.YieldFrom node as string. """
|
|
||||||
yi_val = (" " + node.value.accept(self)) if node.value else ""
|
|
||||||
expr = "yield from" + yi_val
|
|
||||||
if node.parent.is_statement:
|
|
||||||
return expr
|
|
||||||
|
|
||||||
return "(%s)" % (expr,)
|
|
||||||
|
|
||||||
def visit_starred(self, node):
|
|
||||||
"""return Starred node as string"""
|
|
||||||
return "*" + node.value.accept(self)
|
|
||||||
|
|
||||||
# These aren't for real AST nodes, but for inference objects.
|
|
||||||
|
|
||||||
def visit_frozenset(self, node):
|
|
||||||
return node.parent.accept(self)
|
|
||||||
|
|
||||||
def visit_super(self, node):
|
|
||||||
return node.parent.accept(self)
|
|
||||||
|
|
||||||
def visit_uninferable(self, node):
|
|
||||||
return str(node)
|
|
||||||
|
|
||||||
def visit_property(self, node):
|
|
||||||
return node.function.accept(self)
|
|
||||||
|
|
||||||
def visit_evaluatedobject(self, node):
|
|
||||||
return node.original.accept(self)
|
|
||||||
|
|
||||||
|
|
||||||
def _import_string(names):
|
|
||||||
"""return a list of (name, asname) formatted as a string"""
|
|
||||||
_names = []
|
|
||||||
for name, asname in names:
|
|
||||||
if asname is not None:
|
|
||||||
_names.append("%s as %s" % (name, asname))
|
|
||||||
else:
|
|
||||||
_names.append(name)
|
|
||||||
return ", ".join(_names)
|
|
||||||
|
|
||||||
|
|
||||||
# This sets the default indent to 4 spaces.
|
|
||||||
to_code = AsStringVisitor(" ")
|
|
||||||
|
|
@ -1,548 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com>
|
|
||||||
# Copyright (c) 2014-2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2014 Google, Inc.
|
|
||||||
# Copyright (c) 2014 Eevee (Alex Munroe) <amunroe@yelp.com>
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
|
|
||||||
# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com>
|
|
||||||
# Copyright (c) 2017 Calen Pennington <calen.pennington@gmail.com>
|
|
||||||
# Copyright (c) 2018-2019 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
# Copyright (c) 2018 Ville Skyttä <ville.skytta@iki.fi>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com>
|
|
||||||
# Copyright (c) 2018 Daniel Colascione <dancol@dancol.org>
|
|
||||||
# Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""This module contains base classes and functions for the nodes and some
|
|
||||||
inference utils.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import builtins
|
|
||||||
import collections
|
|
||||||
|
|
||||||
from astroid import context as contextmod
|
|
||||||
from astroid import exceptions
|
|
||||||
from astroid import util
|
|
||||||
|
|
||||||
objectmodel = util.lazy_import("interpreter.objectmodel")
|
|
||||||
helpers = util.lazy_import("helpers")
|
|
||||||
BUILTINS = builtins.__name__
|
|
||||||
manager = util.lazy_import("manager")
|
|
||||||
MANAGER = manager.AstroidManager()
|
|
||||||
|
|
||||||
# TODO: check if needs special treatment
|
|
||||||
BUILTINS = "builtins"
|
|
||||||
BOOL_SPECIAL_METHOD = "__bool__"
|
|
||||||
|
|
||||||
PROPERTIES = {BUILTINS + ".property", "abc.abstractproperty"}
|
|
||||||
# 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",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _is_property(meth, context=None):
|
|
||||||
decoratornames = meth.decoratornames(context=context)
|
|
||||||
if PROPERTIES.intersection(decoratornames):
|
|
||||||
return True
|
|
||||||
stripped = {
|
|
||||||
name.split(".")[-1] for name in decoratornames if name is not util.Uninferable
|
|
||||||
}
|
|
||||||
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 inferred is util.Uninferable:
|
|
||||||
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 = None # proxied object may be set by class or by instance
|
|
||||||
|
|
||||||
def __init__(self, proxied=None):
|
|
||||||
if proxied is not None:
|
|
||||||
self._proxied = proxied
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
if name == "_proxied":
|
|
||||||
return getattr(self.__class__, "_proxied")
|
|
||||||
if name in self.__dict__:
|
|
||||||
return self.__dict__[name]
|
|
||||||
return getattr(self._proxied, name)
|
|
||||||
|
|
||||||
def infer(self, context=None):
|
|
||||||
yield self
|
|
||||||
|
|
||||||
|
|
||||||
def _infer_stmts(stmts, context, frame=None):
|
|
||||||
"""Return an iterator on statements inferred by each statement in *stmts*."""
|
|
||||||
inferred = False
|
|
||||||
if context is not None:
|
|
||||||
name = context.lookupname
|
|
||||||
context = context.clone()
|
|
||||||
else:
|
|
||||||
name = None
|
|
||||||
context = contextmod.InferenceContext()
|
|
||||||
|
|
||||||
for stmt in stmts:
|
|
||||||
if stmt is util.Uninferable:
|
|
||||||
yield stmt
|
|
||||||
inferred = True
|
|
||||||
continue
|
|
||||||
context.lookupname = stmt._infer_name(frame, name)
|
|
||||||
try:
|
|
||||||
for inferred in stmt.infer(context=context):
|
|
||||||
yield inferred
|
|
||||||
inferred = True
|
|
||||||
except exceptions.NameInferenceError:
|
|
||||||
continue
|
|
||||||
except exceptions.InferenceError:
|
|
||||||
yield util.Uninferable
|
|
||||||
inferred = True
|
|
||||||
if not inferred:
|
|
||||||
raise exceptions.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 util.Uninferable
|
|
||||||
try:
|
|
||||||
for value in meth.infer_call_result(instance, context=context):
|
|
||||||
if value is util.Uninferable:
|
|
||||||
return value
|
|
||||||
|
|
||||||
inferred = next(value.infer(context=context))
|
|
||||||
return inferred.bool_value()
|
|
||||||
except exceptions.InferenceError:
|
|
||||||
pass
|
|
||||||
return util.Uninferable
|
|
||||||
|
|
||||||
|
|
||||||
class BaseInstance(Proxy):
|
|
||||||
"""An instance base class, which provides lookup methods for potential instances."""
|
|
||||||
|
|
||||||
special_attributes = None
|
|
||||||
|
|
||||||
def display_type(self):
|
|
||||||
return "Instance of"
|
|
||||||
|
|
||||||
def getattr(self, name, context=None, lookupclass=True):
|
|
||||||
try:
|
|
||||||
values = self._proxied.instance_attr(name, context)
|
|
||||||
except exceptions.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 exceptions.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 exceptions.AttributeInferenceError:
|
|
||||||
pass
|
|
||||||
return values
|
|
||||||
|
|
||||||
def igetattr(self, name, context=None):
|
|
||||||
"""inferred getattr"""
|
|
||||||
if not context:
|
|
||||||
context = contextmod.InferenceContext()
|
|
||||||
try:
|
|
||||||
# avoid recursively inferring the same attr on the same class
|
|
||||||
if context.push((self._proxied, name)):
|
|
||||||
raise exceptions.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 exceptions.AttributeInferenceError as error:
|
|
||||||
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 exceptions.AttributeInferenceError as error:
|
|
||||||
raise exceptions.InferenceError(**vars(error)) from error
|
|
||||||
|
|
||||||
def _wrap_attr(self, attrs, context=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, context=None):
|
|
||||||
"""infer what a class instance is returning when called"""
|
|
||||||
context = contextmod.bind_context_to_node(context, self)
|
|
||||||
inferred = False
|
|
||||||
for node in self._proxied.igetattr("__call__", context):
|
|
||||||
if node is util.Uninferable or not node.callable():
|
|
||||||
continue
|
|
||||||
for res in node.infer_call_result(caller, context):
|
|
||||||
inferred = True
|
|
||||||
yield res
|
|
||||||
if not inferred:
|
|
||||||
raise exceptions.InferenceError(node=self, caller=caller, context=context)
|
|
||||||
|
|
||||||
|
|
||||||
class Instance(BaseInstance):
|
|
||||||
"""A special node representing a class instance."""
|
|
||||||
|
|
||||||
# pylint: disable=unnecessary-lambda
|
|
||||||
special_attributes = util.lazy_descriptor(lambda: objectmodel.InstanceModel())
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<Instance of %s.%s at 0x%s>" % (
|
|
||||||
self._proxied.root().name,
|
|
||||||
self._proxied.name,
|
|
||||||
id(self),
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "Instance of %s.%s" % (self._proxied.root().name, self._proxied.name)
|
|
||||||
|
|
||||||
def callable(self):
|
|
||||||
try:
|
|
||||||
self._proxied.getattr("__call__", class_context=False)
|
|
||||||
return True
|
|
||||||
except exceptions.AttributeInferenceError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def pytype(self):
|
|
||||||
return self._proxied.qname()
|
|
||||||
|
|
||||||
def display_type(self):
|
|
||||||
return "Instance of"
|
|
||||||
|
|
||||||
def bool_value(self, context=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 contextmod.InferenceContext()
|
|
||||||
context.callcontext = contextmod.CallContext(args=[])
|
|
||||||
context.boundnode = self
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = _infer_method_result_truth(self, BOOL_SPECIAL_METHOD, context)
|
|
||||||
except (exceptions.InferenceError, exceptions.AttributeInferenceError):
|
|
||||||
# Fallback to __len__.
|
|
||||||
try:
|
|
||||||
result = _infer_method_result_truth(self, "__len__", context)
|
|
||||||
except (exceptions.AttributeInferenceError, exceptions.InferenceError):
|
|
||||||
return True
|
|
||||||
return result
|
|
||||||
|
|
||||||
# This is set in inference.py.
|
|
||||||
def getitem(self, index, context=None):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UnboundMethod(Proxy):
|
|
||||||
"""a special node representing a method not bound to an instance"""
|
|
||||||
|
|
||||||
# pylint: disable=unnecessary-lambda
|
|
||||||
special_attributes = util.lazy_descriptor(lambda: objectmodel.UnboundMethodModel())
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
frame = self._proxied.parent.frame()
|
|
||||||
return "<%s %s of %s at 0x%s" % (
|
|
||||||
self.__class__.__name__,
|
|
||||||
self._proxied.name,
|
|
||||||
frame.qname(),
|
|
||||||
id(self),
|
|
||||||
)
|
|
||||||
|
|
||||||
def implicit_parameters(self):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def is_bound(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def getattr(self, name, context=None):
|
|
||||||
if name in self.special_attributes:
|
|
||||||
return [self.special_attributes.lookup(name)]
|
|
||||||
return self._proxied.getattr(name, context)
|
|
||||||
|
|
||||||
def igetattr(self, name, context=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
|
|
||||||
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 builtin object, the result is an
|
|
||||||
# instance of the class given as first argument.
|
|
||||||
if (
|
|
||||||
self._proxied.name == "__new__"
|
|
||||||
and self._proxied.parent.frame().qname() == "%s.object" % BUILTINS
|
|
||||||
):
|
|
||||||
if caller.args:
|
|
||||||
node_context = context.extra_context.get(caller.args[0])
|
|
||||||
infer = caller.args[0].infer(context=node_context)
|
|
||||||
else:
|
|
||||||
infer = []
|
|
||||||
return (Instance(x) if x is not util.Uninferable else x for x in infer)
|
|
||||||
return self._proxied.infer_call_result(caller, context)
|
|
||||||
|
|
||||||
def bool_value(self, context=None):
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class BoundMethod(UnboundMethod):
|
|
||||||
"""a special node representing a method bound to an instance"""
|
|
||||||
|
|
||||||
# pylint: disable=unnecessary-lambda
|
|
||||||
special_attributes = util.lazy_descriptor(lambda: objectmodel.BoundMethodModel())
|
|
||||||
|
|
||||||
def __init__(self, proxy, bound):
|
|
||||||
UnboundMethod.__init__(self, proxy)
|
|
||||||
self.bound = bound
|
|
||||||
|
|
||||||
def implicit_parameters(self):
|
|
||||||
if self.name == "__new__":
|
|
||||||
# __new__ acts as a classmethod but the class argument is not implicit.
|
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def is_bound(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _infer_type_new_call(self, caller, context):
|
|
||||||
"""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 import node_classes
|
|
||||||
|
|
||||||
# Verify the metaclass
|
|
||||||
mcs = next(caller.args[0].infer(context=context))
|
|
||||||
if mcs.__class__.__name__ != "ClassDef":
|
|
||||||
# Not a valid first argument.
|
|
||||||
return None
|
|
||||||
if not mcs.is_subtype_of("%s.type" % BUILTINS):
|
|
||||||
# Not a valid metaclass.
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Verify the name
|
|
||||||
name = next(caller.args[1].infer(context=context))
|
|
||||||
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
|
|
||||||
bases = next(caller.args[2].infer(context=context))
|
|
||||||
if bases.__class__.__name__ != "Tuple":
|
|
||||||
# Needs to be a tuple.
|
|
||||||
return None
|
|
||||||
inferred_bases = [next(elt.infer(context=context)) for elt in bases.elts]
|
|
||||||
if any(base.__class__.__name__ != "ClassDef" for base in inferred_bases):
|
|
||||||
# All the bases needs to be Classes
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Verify the attributes.
|
|
||||||
attrs = next(caller.args[3].infer(context=context))
|
|
||||||
if attrs.__class__.__name__ != "Dict":
|
|
||||||
# Needs to be a dictionary.
|
|
||||||
return None
|
|
||||||
cls_locals = collections.defaultdict(list)
|
|
||||||
for key, value in attrs.items:
|
|
||||||
key = next(key.infer(context=context))
|
|
||||||
value = next(value.infer(context=context))
|
|
||||||
# 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 = node_classes.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=None):
|
|
||||||
context = contextmod.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=None):
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class Generator(BaseInstance):
|
|
||||||
"""a special node representing a generator.
|
|
||||||
|
|
||||||
Proxied class is set once for all in raw_building.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# pylint: disable=unnecessary-lambda
|
|
||||||
special_attributes = util.lazy_descriptor(lambda: objectmodel.GeneratorModel())
|
|
||||||
|
|
||||||
# pylint: disable=super-init-not-called
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
def callable(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def pytype(self):
|
|
||||||
return "%s.generator" % BUILTINS
|
|
||||||
|
|
||||||
def display_type(self):
|
|
||||||
return "Generator"
|
|
||||||
|
|
||||||
def bool_value(self, context=None):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<Generator(%s) l.%s at 0x%s>" % (
|
|
||||||
self._proxied.name,
|
|
||||||
self.lineno,
|
|
||||||
id(self),
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "Generator(%s)" % (self._proxied.name)
|
|
||||||
|
|
||||||
|
|
||||||
class AsyncGenerator(Generator):
|
|
||||||
"""Special node representing an async generator"""
|
|
||||||
|
|
||||||
def pytype(self):
|
|
||||||
return "%s.async_generator" % BUILTINS
|
|
||||||
|
|
||||||
def display_type(self):
|
|
||||||
return "AsyncGenerator"
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<AsyncGenerator(%s) l.%s at 0x%s>" % (
|
|
||||||
self._proxied.name,
|
|
||||||
self.lineno,
|
|
||||||
id(self),
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "AsyncGenerator(%s)" % (self._proxied.name)
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
from astroid import MANAGER, arguments, nodes, inference_tip, UseInferenceDefault
|
|
||||||
|
|
||||||
|
|
||||||
def infer_namespace(node, context=None):
|
|
||||||
callsite = arguments.CallSite.from_call(node, context=context)
|
|
||||||
if not callsite.keyword_arguments:
|
|
||||||
# Cannot make sense of it.
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
|
|
||||||
class_node = nodes.ClassDef("Namespace", "docstring")
|
|
||||||
class_node.parent = node.parent
|
|
||||||
for attr in set(callsite.keyword_arguments):
|
|
||||||
fake_node = nodes.EmptyNode()
|
|
||||||
fake_node.parent = class_node
|
|
||||||
fake_node.attrname = attr
|
|
||||||
class_node.instance_attrs[attr] = [fake_node]
|
|
||||||
return iter((class_node.instantiate_class(),))
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_namespace(node):
|
|
||||||
func = node.func
|
|
||||||
if isinstance(func, nodes.Attribute):
|
|
||||||
return (
|
|
||||||
func.attrname == "Namespace"
|
|
||||||
and isinstance(func.expr, nodes.Name)
|
|
||||||
and func.expr.name == "argparse"
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.Call, inference_tip(infer_namespace), _looks_like_namespace
|
|
||||||
)
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
"""
|
|
||||||
Astroid hook for the attrs library
|
|
||||||
|
|
||||||
Without this hook pylint reports unsupported-assignment-operation
|
|
||||||
for attrs classes
|
|
||||||
"""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
from astroid import MANAGER
|
|
||||||
|
|
||||||
|
|
||||||
ATTRIB_NAMES = frozenset(("attr.ib", "attrib", "attr.attrib"))
|
|
||||||
ATTRS_NAMES = frozenset(("attr.s", "attrs", "attr.attrs", "attr.attributes"))
|
|
||||||
|
|
||||||
|
|
||||||
def is_decorated_with_attrs(node, decorator_names=ATTRS_NAMES):
|
|
||||||
"""Return True if a decorated node has
|
|
||||||
an attr decorator applied."""
|
|
||||||
if not node.decorators:
|
|
||||||
return False
|
|
||||||
for decorator_attribute in node.decorators.nodes:
|
|
||||||
if isinstance(decorator_attribute, astroid.Call): # decorator with arguments
|
|
||||||
decorator_attribute = decorator_attribute.func
|
|
||||||
if decorator_attribute.as_string() in decorator_names:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def attr_attributes_transform(node):
|
|
||||||
"""Given that the ClassNode has an attr decorator,
|
|
||||||
rewrite class attributes as instance attributes
|
|
||||||
"""
|
|
||||||
# Astroid can't infer this attribute properly
|
|
||||||
# Prevents https://github.com/PyCQA/pylint/issues/1884
|
|
||||||
node.locals["__attrs_attrs__"] = [astroid.Unknown(parent=node)]
|
|
||||||
|
|
||||||
for cdefbodynode in node.body:
|
|
||||||
if not isinstance(cdefbodynode, (astroid.Assign, astroid.AnnAssign)):
|
|
||||||
continue
|
|
||||||
if isinstance(cdefbodynode.value, astroid.Call):
|
|
||||||
if cdefbodynode.value.func.as_string() not in ATTRIB_NAMES:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
targets = (
|
|
||||||
cdefbodynode.targets
|
|
||||||
if hasattr(cdefbodynode, "targets")
|
|
||||||
else [cdefbodynode.target]
|
|
||||||
)
|
|
||||||
for target in targets:
|
|
||||||
|
|
||||||
rhs_node = astroid.Unknown(
|
|
||||||
lineno=cdefbodynode.lineno,
|
|
||||||
col_offset=cdefbodynode.col_offset,
|
|
||||||
parent=cdefbodynode,
|
|
||||||
)
|
|
||||||
node.locals[target.name] = [rhs_node]
|
|
||||||
node.instance_attrs[target.name] = [rhs_node]
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
astroid.ClassDef, attr_attributes_transform, is_decorated_with_attrs
|
|
||||||
)
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for understanding boto3.ServiceRequest()"""
|
|
||||||
import astroid
|
|
||||||
from astroid import MANAGER, extract_node
|
|
||||||
|
|
||||||
BOTO_SERVICE_FACTORY_QUALIFIED_NAME = "boto3.resources.base.ServiceResource"
|
|
||||||
|
|
||||||
|
|
||||||
def service_request_transform(node):
|
|
||||||
"""Transform ServiceResource to look like dynamic classes"""
|
|
||||||
code = """
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
return 0
|
|
||||||
"""
|
|
||||||
func_getattr = extract_node(code)
|
|
||||||
node.locals["__getattr__"] = [func_getattr]
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_boto3_service_request(node):
|
|
||||||
return node.qname() == BOTO_SERVICE_FACTORY_QUALIFIED_NAME
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
astroid.ClassDef, service_request_transform, _looks_like_boto3_service_request
|
|
||||||
)
|
|
||||||
|
|
@ -1,873 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2014-2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2014-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2015 Rene Zhang <rz99@cornell.edu>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
# Copyright (c) 2018 Ville Skyttä <ville.skytta@iki.fi>
|
|
||||||
# Copyright (c) 2019 Stanislav Levin <slev@altlinux.org>
|
|
||||||
# Copyright (c) 2019 David Liu <david@cs.toronto.edu>
|
|
||||||
# Copyright (c) 2019 Bryce Guinta <bryce.guinta@protonmail.com>
|
|
||||||
# Copyright (c) 2019 Frédéric Chapoton <fchapoton2@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for various builtins."""
|
|
||||||
|
|
||||||
from functools import partial
|
|
||||||
from textwrap import dedent
|
|
||||||
|
|
||||||
import six
|
|
||||||
from astroid import (
|
|
||||||
MANAGER,
|
|
||||||
UseInferenceDefault,
|
|
||||||
AttributeInferenceError,
|
|
||||||
inference_tip,
|
|
||||||
InferenceError,
|
|
||||||
NameInferenceError,
|
|
||||||
AstroidTypeError,
|
|
||||||
MroError,
|
|
||||||
)
|
|
||||||
from astroid import arguments
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
from astroid import helpers
|
|
||||||
from astroid import nodes
|
|
||||||
from astroid import objects
|
|
||||||
from astroid import scoped_nodes
|
|
||||||
from astroid import util
|
|
||||||
|
|
||||||
|
|
||||||
OBJECT_DUNDER_NEW = "object.__new__"
|
|
||||||
|
|
||||||
|
|
||||||
def _extend_str(class_node, rvalue):
|
|
||||||
"""function to extend builtin str/unicode class"""
|
|
||||||
code = dedent(
|
|
||||||
"""
|
|
||||||
class whatever(object):
|
|
||||||
def join(self, iterable):
|
|
||||||
return {rvalue}
|
|
||||||
def replace(self, old, new, count=None):
|
|
||||||
return {rvalue}
|
|
||||||
def format(self, *args, **kwargs):
|
|
||||||
return {rvalue}
|
|
||||||
def encode(self, encoding='ascii', errors=None):
|
|
||||||
return ''
|
|
||||||
def decode(self, encoding='ascii', errors=None):
|
|
||||||
return u''
|
|
||||||
def capitalize(self):
|
|
||||||
return {rvalue}
|
|
||||||
def title(self):
|
|
||||||
return {rvalue}
|
|
||||||
def lower(self):
|
|
||||||
return {rvalue}
|
|
||||||
def upper(self):
|
|
||||||
return {rvalue}
|
|
||||||
def swapcase(self):
|
|
||||||
return {rvalue}
|
|
||||||
def index(self, sub, start=None, end=None):
|
|
||||||
return 0
|
|
||||||
def find(self, sub, start=None, end=None):
|
|
||||||
return 0
|
|
||||||
def count(self, sub, start=None, end=None):
|
|
||||||
return 0
|
|
||||||
def strip(self, chars=None):
|
|
||||||
return {rvalue}
|
|
||||||
def lstrip(self, chars=None):
|
|
||||||
return {rvalue}
|
|
||||||
def rstrip(self, chars=None):
|
|
||||||
return {rvalue}
|
|
||||||
def rjust(self, width, fillchar=None):
|
|
||||||
return {rvalue}
|
|
||||||
def center(self, width, fillchar=None):
|
|
||||||
return {rvalue}
|
|
||||||
def ljust(self, width, fillchar=None):
|
|
||||||
return {rvalue}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
code = code.format(rvalue=rvalue)
|
|
||||||
fake = AstroidBuilder(MANAGER).string_build(code)["whatever"]
|
|
||||||
for method in fake.mymethods():
|
|
||||||
method.parent = class_node
|
|
||||||
method.lineno = None
|
|
||||||
method.col_offset = None
|
|
||||||
if "__class__" in method.locals:
|
|
||||||
method.locals["__class__"] = [class_node]
|
|
||||||
class_node.locals[method.name] = [method]
|
|
||||||
method.parent = class_node
|
|
||||||
|
|
||||||
|
|
||||||
def _extend_builtins(class_transforms):
|
|
||||||
builtin_ast = MANAGER.builtins_module
|
|
||||||
for class_name, transform in class_transforms.items():
|
|
||||||
transform(builtin_ast[class_name])
|
|
||||||
|
|
||||||
|
|
||||||
_extend_builtins(
|
|
||||||
{
|
|
||||||
"bytes": partial(_extend_str, rvalue="b''"),
|
|
||||||
"str": partial(_extend_str, rvalue="''"),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _builtin_filter_predicate(node, builtin_name):
|
|
||||||
if isinstance(node.func, nodes.Name) and node.func.name == builtin_name:
|
|
||||||
return True
|
|
||||||
if isinstance(node.func, nodes.Attribute):
|
|
||||||
return (
|
|
||||||
node.func.attrname == "fromkeys"
|
|
||||||
and isinstance(node.func.expr, nodes.Name)
|
|
||||||
and node.func.expr.name == "dict"
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def register_builtin_transform(transform, builtin_name):
|
|
||||||
"""Register a new transform function for the given *builtin_name*.
|
|
||||||
|
|
||||||
The transform function must accept two parameters, a node and
|
|
||||||
an optional context.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _transform_wrapper(node, context=None):
|
|
||||||
result = transform(node, context=context)
|
|
||||||
if result:
|
|
||||||
if not result.parent:
|
|
||||||
# Let the transformation function determine
|
|
||||||
# the parent for its result. Otherwise,
|
|
||||||
# we set it to be the node we transformed from.
|
|
||||||
result.parent = node
|
|
||||||
|
|
||||||
if result.lineno is None:
|
|
||||||
result.lineno = node.lineno
|
|
||||||
if result.col_offset is None:
|
|
||||||
result.col_offset = node.col_offset
|
|
||||||
return iter([result])
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.Call,
|
|
||||||
inference_tip(_transform_wrapper),
|
|
||||||
partial(_builtin_filter_predicate, builtin_name=builtin_name),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _container_generic_inference(node, context, node_type, transform):
|
|
||||||
args = node.args
|
|
||||||
if not args:
|
|
||||||
return node_type()
|
|
||||||
if len(node.args) > 1:
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
|
|
||||||
(arg,) = args
|
|
||||||
transformed = transform(arg)
|
|
||||||
if not transformed:
|
|
||||||
try:
|
|
||||||
inferred = next(arg.infer(context=context))
|
|
||||||
except (InferenceError, StopIteration):
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
if inferred is util.Uninferable:
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
transformed = transform(inferred)
|
|
||||||
if not transformed or transformed is util.Uninferable:
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
return transformed
|
|
||||||
|
|
||||||
|
|
||||||
def _container_generic_transform(arg, context, klass, iterables, build_elts):
|
|
||||||
if isinstance(arg, klass):
|
|
||||||
return arg
|
|
||||||
elif isinstance(arg, iterables):
|
|
||||||
if all(isinstance(elt, nodes.Const) for elt in arg.elts):
|
|
||||||
elts = [elt.value for elt in arg.elts]
|
|
||||||
else:
|
|
||||||
# TODO: Does not handle deduplication for sets.
|
|
||||||
elts = []
|
|
||||||
for element in arg.elts:
|
|
||||||
inferred = helpers.safe_infer(element, context=context)
|
|
||||||
if inferred:
|
|
||||||
evaluated_object = nodes.EvaluatedObject(
|
|
||||||
original=element, value=inferred
|
|
||||||
)
|
|
||||||
elts.append(evaluated_object)
|
|
||||||
elif isinstance(arg, nodes.Dict):
|
|
||||||
# Dicts need to have consts as strings already.
|
|
||||||
if not all(isinstance(elt[0], nodes.Const) for elt in arg.items):
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
elts = [item[0].value for item in arg.items]
|
|
||||||
elif isinstance(arg, nodes.Const) and isinstance(
|
|
||||||
arg.value, (six.string_types, six.binary_type)
|
|
||||||
):
|
|
||||||
elts = arg.value
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
return klass.from_elements(elts=build_elts(elts))
|
|
||||||
|
|
||||||
|
|
||||||
def _infer_builtin_container(
|
|
||||||
node, context, klass=None, iterables=None, build_elts=None
|
|
||||||
):
|
|
||||||
transform_func = partial(
|
|
||||||
_container_generic_transform,
|
|
||||||
context=context,
|
|
||||||
klass=klass,
|
|
||||||
iterables=iterables,
|
|
||||||
build_elts=build_elts,
|
|
||||||
)
|
|
||||||
|
|
||||||
return _container_generic_inference(node, context, klass, transform_func)
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
|
||||||
infer_tuple = partial(
|
|
||||||
_infer_builtin_container,
|
|
||||||
klass=nodes.Tuple,
|
|
||||||
iterables=(
|
|
||||||
nodes.List,
|
|
||||||
nodes.Set,
|
|
||||||
objects.FrozenSet,
|
|
||||||
objects.DictItems,
|
|
||||||
objects.DictKeys,
|
|
||||||
objects.DictValues,
|
|
||||||
),
|
|
||||||
build_elts=tuple,
|
|
||||||
)
|
|
||||||
|
|
||||||
infer_list = partial(
|
|
||||||
_infer_builtin_container,
|
|
||||||
klass=nodes.List,
|
|
||||||
iterables=(
|
|
||||||
nodes.Tuple,
|
|
||||||
nodes.Set,
|
|
||||||
objects.FrozenSet,
|
|
||||||
objects.DictItems,
|
|
||||||
objects.DictKeys,
|
|
||||||
objects.DictValues,
|
|
||||||
),
|
|
||||||
build_elts=list,
|
|
||||||
)
|
|
||||||
|
|
||||||
infer_set = partial(
|
|
||||||
_infer_builtin_container,
|
|
||||||
klass=nodes.Set,
|
|
||||||
iterables=(nodes.List, nodes.Tuple, objects.FrozenSet, objects.DictKeys),
|
|
||||||
build_elts=set,
|
|
||||||
)
|
|
||||||
|
|
||||||
infer_frozenset = partial(
|
|
||||||
_infer_builtin_container,
|
|
||||||
klass=objects.FrozenSet,
|
|
||||||
iterables=(nodes.List, nodes.Tuple, nodes.Set, objects.FrozenSet, objects.DictKeys),
|
|
||||||
build_elts=frozenset,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_elts(arg, context):
|
|
||||||
is_iterable = lambda n: isinstance(n, (nodes.List, nodes.Tuple, nodes.Set))
|
|
||||||
try:
|
|
||||||
inferred = next(arg.infer(context))
|
|
||||||
except (InferenceError, NameInferenceError):
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
if isinstance(inferred, nodes.Dict):
|
|
||||||
items = inferred.items
|
|
||||||
elif is_iterable(inferred):
|
|
||||||
items = []
|
|
||||||
for elt in inferred.elts:
|
|
||||||
# If an item is not a pair of two items,
|
|
||||||
# then fallback to the default inference.
|
|
||||||
# Also, take in consideration only hashable items,
|
|
||||||
# tuples and consts. We are choosing Names as well.
|
|
||||||
if not is_iterable(elt):
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
if len(elt.elts) != 2:
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
if not isinstance(elt.elts[0], (nodes.Tuple, nodes.Const, nodes.Name)):
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
items.append(tuple(elt.elts))
|
|
||||||
else:
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
return items
|
|
||||||
|
|
||||||
|
|
||||||
def infer_dict(node, context=None):
|
|
||||||
"""Try to infer a dict call to a Dict node.
|
|
||||||
|
|
||||||
The function treats the following cases:
|
|
||||||
|
|
||||||
* dict()
|
|
||||||
* dict(mapping)
|
|
||||||
* dict(iterable)
|
|
||||||
* dict(iterable, **kwargs)
|
|
||||||
* dict(mapping, **kwargs)
|
|
||||||
* dict(**kwargs)
|
|
||||||
|
|
||||||
If a case can't be inferred, we'll fallback to default inference.
|
|
||||||
"""
|
|
||||||
call = arguments.CallSite.from_call(node, context=context)
|
|
||||||
if call.has_invalid_arguments() or call.has_invalid_keywords():
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
args = call.positional_arguments
|
|
||||||
kwargs = list(call.keyword_arguments.items())
|
|
||||||
|
|
||||||
if not args and not kwargs:
|
|
||||||
# dict()
|
|
||||||
return nodes.Dict()
|
|
||||||
elif kwargs and not args:
|
|
||||||
# dict(a=1, b=2, c=4)
|
|
||||||
items = [(nodes.Const(key), value) for key, value in kwargs]
|
|
||||||
elif len(args) == 1 and kwargs:
|
|
||||||
# dict(some_iterable, b=2, c=4)
|
|
||||||
elts = _get_elts(args[0], context)
|
|
||||||
keys = [(nodes.Const(key), value) for key, value in kwargs]
|
|
||||||
items = elts + keys
|
|
||||||
elif len(args) == 1:
|
|
||||||
items = _get_elts(args[0], context)
|
|
||||||
else:
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
|
|
||||||
value = nodes.Dict(
|
|
||||||
col_offset=node.col_offset, lineno=node.lineno, parent=node.parent
|
|
||||||
)
|
|
||||||
value.postinit(items)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def infer_super(node, context=None):
|
|
||||||
"""Understand super calls.
|
|
||||||
|
|
||||||
There are some restrictions for what can be understood:
|
|
||||||
|
|
||||||
* unbounded super (one argument form) is not understood.
|
|
||||||
|
|
||||||
* if the super call is not inside a function (classmethod or method),
|
|
||||||
then the default inference will be used.
|
|
||||||
|
|
||||||
* if the super arguments can't be inferred, the default inference
|
|
||||||
will be used.
|
|
||||||
"""
|
|
||||||
if len(node.args) == 1:
|
|
||||||
# Ignore unbounded super.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
scope = node.scope()
|
|
||||||
if not isinstance(scope, nodes.FunctionDef):
|
|
||||||
# Ignore non-method uses of super.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
if scope.type not in ("classmethod", "method"):
|
|
||||||
# Not interested in staticmethods.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
cls = scoped_nodes.get_wrapping_class(scope)
|
|
||||||
if not len(node.args):
|
|
||||||
mro_pointer = cls
|
|
||||||
# In we are in a classmethod, the interpreter will fill
|
|
||||||
# automatically the class as the second argument, not an instance.
|
|
||||||
if scope.type == "classmethod":
|
|
||||||
mro_type = cls
|
|
||||||
else:
|
|
||||||
mro_type = cls.instantiate_class()
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
mro_pointer = next(node.args[0].infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
try:
|
|
||||||
mro_type = next(node.args[1].infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if mro_pointer is util.Uninferable or mro_type is util.Uninferable:
|
|
||||||
# No way we could understand this.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
super_obj = objects.Super(
|
|
||||||
mro_pointer=mro_pointer, mro_type=mro_type, self_class=cls, scope=scope
|
|
||||||
)
|
|
||||||
super_obj.parent = node
|
|
||||||
return super_obj
|
|
||||||
|
|
||||||
|
|
||||||
def _infer_getattr_args(node, context):
|
|
||||||
if len(node.args) not in (2, 3):
|
|
||||||
# Not a valid getattr call.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
try:
|
|
||||||
obj = next(node.args[0].infer(context=context))
|
|
||||||
attr = next(node.args[1].infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if obj is util.Uninferable or attr is util.Uninferable:
|
|
||||||
# If one of the arguments is something we can't infer,
|
|
||||||
# then also make the result of the getattr call something
|
|
||||||
# which is unknown.
|
|
||||||
return util.Uninferable, util.Uninferable
|
|
||||||
|
|
||||||
is_string = isinstance(attr, nodes.Const) and isinstance(
|
|
||||||
attr.value, six.string_types
|
|
||||||
)
|
|
||||||
if not is_string:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
return obj, attr.value
|
|
||||||
|
|
||||||
|
|
||||||
def infer_getattr(node, context=None):
|
|
||||||
"""Understand getattr calls
|
|
||||||
|
|
||||||
If one of the arguments is an Uninferable object, then the
|
|
||||||
result will be an Uninferable object. Otherwise, the normal attribute
|
|
||||||
lookup will be done.
|
|
||||||
"""
|
|
||||||
obj, attr = _infer_getattr_args(node, context)
|
|
||||||
if (
|
|
||||||
obj is util.Uninferable
|
|
||||||
or attr is util.Uninferable
|
|
||||||
or not hasattr(obj, "igetattr")
|
|
||||||
):
|
|
||||||
return util.Uninferable
|
|
||||||
|
|
||||||
try:
|
|
||||||
return next(obj.igetattr(attr, context=context))
|
|
||||||
except (StopIteration, InferenceError, AttributeInferenceError):
|
|
||||||
if len(node.args) == 3:
|
|
||||||
# Try to infer the default and return it instead.
|
|
||||||
try:
|
|
||||||
return next(node.args[2].infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
|
|
||||||
def infer_hasattr(node, context=None):
|
|
||||||
"""Understand hasattr calls
|
|
||||||
|
|
||||||
This always guarantees three possible outcomes for calling
|
|
||||||
hasattr: Const(False) when we are sure that the object
|
|
||||||
doesn't have the intended attribute, Const(True) when
|
|
||||||
we know that the object has the attribute and Uninferable
|
|
||||||
when we are unsure of the outcome of the function call.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
obj, attr = _infer_getattr_args(node, context)
|
|
||||||
if (
|
|
||||||
obj is util.Uninferable
|
|
||||||
or attr is util.Uninferable
|
|
||||||
or not hasattr(obj, "getattr")
|
|
||||||
):
|
|
||||||
return util.Uninferable
|
|
||||||
obj.getattr(attr, context=context)
|
|
||||||
except UseInferenceDefault:
|
|
||||||
# Can't infer something from this function call.
|
|
||||||
return util.Uninferable
|
|
||||||
except AttributeInferenceError:
|
|
||||||
# Doesn't have it.
|
|
||||||
return nodes.Const(False)
|
|
||||||
return nodes.Const(True)
|
|
||||||
|
|
||||||
|
|
||||||
def infer_callable(node, context=None):
|
|
||||||
"""Understand callable calls
|
|
||||||
|
|
||||||
This follows Python's semantics, where an object
|
|
||||||
is callable if it provides an attribute __call__,
|
|
||||||
even though that attribute is something which can't be
|
|
||||||
called.
|
|
||||||
"""
|
|
||||||
if len(node.args) != 1:
|
|
||||||
# Invalid callable call.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
argument = node.args[0]
|
|
||||||
try:
|
|
||||||
inferred = next(argument.infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
return util.Uninferable
|
|
||||||
if inferred is util.Uninferable:
|
|
||||||
return util.Uninferable
|
|
||||||
return nodes.Const(inferred.callable())
|
|
||||||
|
|
||||||
|
|
||||||
def infer_property(node, context=None):
|
|
||||||
"""Understand `property` class
|
|
||||||
|
|
||||||
This only infers the output of `property`
|
|
||||||
call, not the arguments themselves.
|
|
||||||
"""
|
|
||||||
if len(node.args) < 1:
|
|
||||||
# Invalid property call.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
getter = node.args[0]
|
|
||||||
try:
|
|
||||||
inferred = next(getter.infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if not isinstance(inferred, (nodes.FunctionDef, nodes.Lambda)):
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
return objects.Property(
|
|
||||||
function=inferred,
|
|
||||||
name=inferred.name,
|
|
||||||
doc=getattr(inferred, "doc", None),
|
|
||||||
lineno=node.lineno,
|
|
||||||
parent=node,
|
|
||||||
col_offset=node.col_offset,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def infer_bool(node, context=None):
|
|
||||||
"""Understand bool calls."""
|
|
||||||
if len(node.args) > 1:
|
|
||||||
# Invalid bool call.
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if not node.args:
|
|
||||||
return nodes.Const(False)
|
|
||||||
|
|
||||||
argument = node.args[0]
|
|
||||||
try:
|
|
||||||
inferred = next(argument.infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
return util.Uninferable
|
|
||||||
if inferred is util.Uninferable:
|
|
||||||
return util.Uninferable
|
|
||||||
|
|
||||||
bool_value = inferred.bool_value(context=context)
|
|
||||||
if bool_value is util.Uninferable:
|
|
||||||
return util.Uninferable
|
|
||||||
return nodes.Const(bool_value)
|
|
||||||
|
|
||||||
|
|
||||||
def infer_type(node, context=None):
|
|
||||||
"""Understand the one-argument form of *type*."""
|
|
||||||
if len(node.args) != 1:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
return helpers.object_type(node.args[0], context)
|
|
||||||
|
|
||||||
|
|
||||||
def infer_slice(node, context=None):
|
|
||||||
"""Understand `slice` calls."""
|
|
||||||
args = node.args
|
|
||||||
if not 0 < len(args) <= 3:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
infer_func = partial(helpers.safe_infer, context=context)
|
|
||||||
args = [infer_func(arg) for arg in args]
|
|
||||||
for arg in args:
|
|
||||||
if not arg or arg is util.Uninferable:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
if not isinstance(arg, nodes.Const):
|
|
||||||
raise UseInferenceDefault
|
|
||||||
if not isinstance(arg.value, (type(None), int)):
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if len(args) < 3:
|
|
||||||
# Make sure we have 3 arguments.
|
|
||||||
args.extend([None] * (3 - len(args)))
|
|
||||||
|
|
||||||
slice_node = nodes.Slice(
|
|
||||||
lineno=node.lineno, col_offset=node.col_offset, parent=node.parent
|
|
||||||
)
|
|
||||||
slice_node.postinit(*args)
|
|
||||||
return slice_node
|
|
||||||
|
|
||||||
|
|
||||||
def _infer_object__new__decorator(node, context=None):
|
|
||||||
# Instantiate class immediately
|
|
||||||
# since that's what @object.__new__ does
|
|
||||||
return iter((node.instantiate_class(),))
|
|
||||||
|
|
||||||
|
|
||||||
def _infer_object__new__decorator_check(node):
|
|
||||||
"""Predicate before inference_tip
|
|
||||||
|
|
||||||
Check if the given ClassDef has an @object.__new__ decorator
|
|
||||||
"""
|
|
||||||
if not node.decorators:
|
|
||||||
return False
|
|
||||||
|
|
||||||
for decorator in node.decorators.nodes:
|
|
||||||
if isinstance(decorator, nodes.Attribute):
|
|
||||||
if decorator.as_string() == OBJECT_DUNDER_NEW:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def infer_issubclass(callnode, context=None):
|
|
||||||
"""Infer issubclass() calls
|
|
||||||
|
|
||||||
:param nodes.Call callnode: an `issubclass` call
|
|
||||||
:param InferenceContext: the context for the inference
|
|
||||||
:rtype nodes.Const: Boolean Const value of the `issubclass` call
|
|
||||||
:raises UseInferenceDefault: If the node cannot be inferred
|
|
||||||
"""
|
|
||||||
call = arguments.CallSite.from_call(callnode, context=context)
|
|
||||||
if call.keyword_arguments:
|
|
||||||
# issubclass doesn't support keyword arguments
|
|
||||||
raise UseInferenceDefault("TypeError: issubclass() takes no keyword arguments")
|
|
||||||
if len(call.positional_arguments) != 2:
|
|
||||||
raise UseInferenceDefault(
|
|
||||||
"Expected two arguments, got {count}".format(
|
|
||||||
count=len(call.positional_arguments)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# The left hand argument is the obj to be checked
|
|
||||||
obj_node, class_or_tuple_node = call.positional_arguments
|
|
||||||
|
|
||||||
try:
|
|
||||||
obj_type = next(obj_node.infer(context=context))
|
|
||||||
except InferenceError as exc:
|
|
||||||
raise UseInferenceDefault from exc
|
|
||||||
if not isinstance(obj_type, nodes.ClassDef):
|
|
||||||
raise UseInferenceDefault("TypeError: arg 1 must be class")
|
|
||||||
|
|
||||||
# The right hand argument is the class(es) that the given
|
|
||||||
# object is to be checked against.
|
|
||||||
try:
|
|
||||||
class_container = _class_or_tuple_to_container(
|
|
||||||
class_or_tuple_node, context=context
|
|
||||||
)
|
|
||||||
except InferenceError as exc:
|
|
||||||
raise UseInferenceDefault from exc
|
|
||||||
try:
|
|
||||||
issubclass_bool = helpers.object_issubclass(obj_type, class_container, context)
|
|
||||||
except AstroidTypeError as exc:
|
|
||||||
raise UseInferenceDefault("TypeError: " + str(exc)) from exc
|
|
||||||
except MroError as exc:
|
|
||||||
raise UseInferenceDefault from exc
|
|
||||||
return nodes.Const(issubclass_bool)
|
|
||||||
|
|
||||||
|
|
||||||
def infer_isinstance(callnode, context=None):
|
|
||||||
"""Infer isinstance calls
|
|
||||||
|
|
||||||
:param nodes.Call callnode: an isinstance call
|
|
||||||
:param InferenceContext: context for call
|
|
||||||
(currently unused but is a common interface for inference)
|
|
||||||
:rtype nodes.Const: Boolean Const value of isinstance call
|
|
||||||
|
|
||||||
:raises UseInferenceDefault: If the node cannot be inferred
|
|
||||||
"""
|
|
||||||
call = arguments.CallSite.from_call(callnode, context=context)
|
|
||||||
if call.keyword_arguments:
|
|
||||||
# isinstance doesn't support keyword arguments
|
|
||||||
raise UseInferenceDefault("TypeError: isinstance() takes no keyword arguments")
|
|
||||||
if len(call.positional_arguments) != 2:
|
|
||||||
raise UseInferenceDefault(
|
|
||||||
"Expected two arguments, got {count}".format(
|
|
||||||
count=len(call.positional_arguments)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# The left hand argument is the obj to be checked
|
|
||||||
obj_node, class_or_tuple_node = call.positional_arguments
|
|
||||||
# The right hand argument is the class(es) that the given
|
|
||||||
# obj is to be check is an instance of
|
|
||||||
try:
|
|
||||||
class_container = _class_or_tuple_to_container(
|
|
||||||
class_or_tuple_node, context=context
|
|
||||||
)
|
|
||||||
except InferenceError:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
try:
|
|
||||||
isinstance_bool = helpers.object_isinstance(obj_node, class_container, context)
|
|
||||||
except AstroidTypeError as exc:
|
|
||||||
raise UseInferenceDefault("TypeError: " + str(exc))
|
|
||||||
except MroError as exc:
|
|
||||||
raise UseInferenceDefault from exc
|
|
||||||
if isinstance_bool is util.Uninferable:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
return nodes.Const(isinstance_bool)
|
|
||||||
|
|
||||||
|
|
||||||
def _class_or_tuple_to_container(node, context=None):
|
|
||||||
# Move inferences results into container
|
|
||||||
# to simplify later logic
|
|
||||||
# raises InferenceError if any of the inferences fall through
|
|
||||||
node_infer = next(node.infer(context=context))
|
|
||||||
# arg2 MUST be a type or a TUPLE of types
|
|
||||||
# for isinstance
|
|
||||||
if isinstance(node_infer, nodes.Tuple):
|
|
||||||
class_container = [
|
|
||||||
next(node.infer(context=context)) for node in node_infer.elts
|
|
||||||
]
|
|
||||||
class_container = [
|
|
||||||
klass_node for klass_node in class_container if klass_node is not None
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
class_container = [node_infer]
|
|
||||||
return class_container
|
|
||||||
|
|
||||||
|
|
||||||
def infer_len(node, context=None):
|
|
||||||
"""Infer length calls
|
|
||||||
|
|
||||||
:param nodes.Call node: len call to infer
|
|
||||||
:param context.InferenceContext: node context
|
|
||||||
:rtype nodes.Const: a Const node with the inferred length, if possible
|
|
||||||
"""
|
|
||||||
call = arguments.CallSite.from_call(node, context=context)
|
|
||||||
if call.keyword_arguments:
|
|
||||||
raise UseInferenceDefault("TypeError: len() must take no keyword arguments")
|
|
||||||
if len(call.positional_arguments) != 1:
|
|
||||||
raise UseInferenceDefault(
|
|
||||||
"TypeError: len() must take exactly one argument "
|
|
||||||
"({len}) given".format(len=len(call.positional_arguments))
|
|
||||||
)
|
|
||||||
[argument_node] = call.positional_arguments
|
|
||||||
try:
|
|
||||||
return nodes.Const(helpers.object_len(argument_node, context=context))
|
|
||||||
except (AstroidTypeError, InferenceError) as exc:
|
|
||||||
raise UseInferenceDefault(str(exc)) from exc
|
|
||||||
|
|
||||||
|
|
||||||
def infer_str(node, context=None):
|
|
||||||
"""Infer str() calls
|
|
||||||
|
|
||||||
:param nodes.Call node: str() call to infer
|
|
||||||
:param context.InferenceContext: node context
|
|
||||||
:rtype nodes.Const: a Const containing an empty string
|
|
||||||
"""
|
|
||||||
call = arguments.CallSite.from_call(node, context=context)
|
|
||||||
if call.keyword_arguments:
|
|
||||||
raise UseInferenceDefault("TypeError: str() must take no keyword arguments")
|
|
||||||
try:
|
|
||||||
return nodes.Const("")
|
|
||||||
except (AstroidTypeError, InferenceError) as exc:
|
|
||||||
raise UseInferenceDefault(str(exc)) from exc
|
|
||||||
|
|
||||||
|
|
||||||
def infer_int(node, context=None):
|
|
||||||
"""Infer int() calls
|
|
||||||
|
|
||||||
:param nodes.Call node: int() call to infer
|
|
||||||
:param context.InferenceContext: node context
|
|
||||||
:rtype nodes.Const: a Const containing the integer value of the int() call
|
|
||||||
"""
|
|
||||||
call = arguments.CallSite.from_call(node, context=context)
|
|
||||||
if call.keyword_arguments:
|
|
||||||
raise UseInferenceDefault("TypeError: int() must take no keyword arguments")
|
|
||||||
|
|
||||||
if call.positional_arguments:
|
|
||||||
try:
|
|
||||||
first_value = next(call.positional_arguments[0].infer(context=context))
|
|
||||||
except (InferenceError, StopIteration) as exc:
|
|
||||||
raise UseInferenceDefault(str(exc)) from exc
|
|
||||||
|
|
||||||
if first_value is util.Uninferable:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if isinstance(first_value, nodes.Const) and isinstance(
|
|
||||||
first_value.value, (int, str)
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
actual_value = int(first_value.value)
|
|
||||||
except ValueError:
|
|
||||||
return nodes.Const(0)
|
|
||||||
return nodes.Const(actual_value)
|
|
||||||
|
|
||||||
return nodes.Const(0)
|
|
||||||
|
|
||||||
|
|
||||||
def infer_dict_fromkeys(node, context=None):
|
|
||||||
"""Infer dict.fromkeys
|
|
||||||
|
|
||||||
:param nodes.Call node: dict.fromkeys() call to infer
|
|
||||||
:param context.InferenceContext: node context
|
|
||||||
:rtype nodes.Dict:
|
|
||||||
a Dictionary containing the values that astroid was able to infer.
|
|
||||||
In case the inference failed for any reason, an empty dictionary
|
|
||||||
will be inferred instead.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _build_dict_with_elements(elements):
|
|
||||||
new_node = nodes.Dict(
|
|
||||||
col_offset=node.col_offset, lineno=node.lineno, parent=node.parent
|
|
||||||
)
|
|
||||||
new_node.postinit(elements)
|
|
||||||
return new_node
|
|
||||||
|
|
||||||
call = arguments.CallSite.from_call(node, context=context)
|
|
||||||
if call.keyword_arguments:
|
|
||||||
raise UseInferenceDefault("TypeError: int() must take no keyword arguments")
|
|
||||||
if len(call.positional_arguments) not in {1, 2}:
|
|
||||||
raise UseInferenceDefault(
|
|
||||||
"TypeError: Needs between 1 and 2 positional arguments"
|
|
||||||
)
|
|
||||||
|
|
||||||
default = nodes.Const(None)
|
|
||||||
values = call.positional_arguments[0]
|
|
||||||
try:
|
|
||||||
inferred_values = next(values.infer(context=context))
|
|
||||||
except InferenceError:
|
|
||||||
return _build_dict_with_elements([])
|
|
||||||
if inferred_values is util.Uninferable:
|
|
||||||
return _build_dict_with_elements([])
|
|
||||||
|
|
||||||
# Limit to a couple of potential values, as this can become pretty complicated
|
|
||||||
accepted_iterable_elements = (nodes.Const,)
|
|
||||||
if isinstance(inferred_values, (nodes.List, nodes.Set, nodes.Tuple)):
|
|
||||||
elements = inferred_values.elts
|
|
||||||
for element in elements:
|
|
||||||
if not isinstance(element, accepted_iterable_elements):
|
|
||||||
# Fallback to an empty dict
|
|
||||||
return _build_dict_with_elements([])
|
|
||||||
|
|
||||||
elements_with_value = [(element, default) for element in elements]
|
|
||||||
return _build_dict_with_elements(elements_with_value)
|
|
||||||
|
|
||||||
elif isinstance(inferred_values, nodes.Const) and isinstance(
|
|
||||||
inferred_values.value, (str, bytes)
|
|
||||||
):
|
|
||||||
elements = [
|
|
||||||
(nodes.Const(element), default) for element in inferred_values.value
|
|
||||||
]
|
|
||||||
return _build_dict_with_elements(elements)
|
|
||||||
elif isinstance(inferred_values, nodes.Dict):
|
|
||||||
keys = inferred_values.itered()
|
|
||||||
for key in keys:
|
|
||||||
if not isinstance(key, accepted_iterable_elements):
|
|
||||||
# Fallback to an empty dict
|
|
||||||
return _build_dict_with_elements([])
|
|
||||||
|
|
||||||
elements_with_value = [(element, default) for element in keys]
|
|
||||||
return _build_dict_with_elements(elements_with_value)
|
|
||||||
|
|
||||||
# Fallback to an empty dictionary
|
|
||||||
return _build_dict_with_elements([])
|
|
||||||
|
|
||||||
|
|
||||||
# Builtins inference
|
|
||||||
register_builtin_transform(infer_bool, "bool")
|
|
||||||
register_builtin_transform(infer_super, "super")
|
|
||||||
register_builtin_transform(infer_callable, "callable")
|
|
||||||
register_builtin_transform(infer_property, "property")
|
|
||||||
register_builtin_transform(infer_getattr, "getattr")
|
|
||||||
register_builtin_transform(infer_hasattr, "hasattr")
|
|
||||||
register_builtin_transform(infer_tuple, "tuple")
|
|
||||||
register_builtin_transform(infer_set, "set")
|
|
||||||
register_builtin_transform(infer_list, "list")
|
|
||||||
register_builtin_transform(infer_dict, "dict")
|
|
||||||
register_builtin_transform(infer_frozenset, "frozenset")
|
|
||||||
register_builtin_transform(infer_type, "type")
|
|
||||||
register_builtin_transform(infer_slice, "slice")
|
|
||||||
register_builtin_transform(infer_isinstance, "isinstance")
|
|
||||||
register_builtin_transform(infer_issubclass, "issubclass")
|
|
||||||
register_builtin_transform(infer_len, "len")
|
|
||||||
register_builtin_transform(infer_str, "str")
|
|
||||||
register_builtin_transform(infer_int, "int")
|
|
||||||
register_builtin_transform(infer_dict_fromkeys, "dict.fromkeys")
|
|
||||||
|
|
||||||
|
|
||||||
# Infer object.__new__ calls
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.ClassDef,
|
|
||||||
inference_tip(_infer_object__new__decorator),
|
|
||||||
_infer_object__new__decorator_check,
|
|
||||||
)
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com>
|
|
||||||
# Copyright (c) 2017 Derek Gustafson <degustaf@gmail.com>
|
|
||||||
# Copyright (c) 2018 Ioana Tagirta <ioana.tagirta@gmail.com>
|
|
||||||
# Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def _collections_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
class defaultdict(dict):
|
|
||||||
default_factory = None
|
|
||||||
def __missing__(self, key): pass
|
|
||||||
def __getitem__(self, key): return default_factory
|
|
||||||
|
|
||||||
"""
|
|
||||||
+ _deque_mock()
|
|
||||||
+ _ordered_dict_mock()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _deque_mock():
|
|
||||||
base_deque_class = """
|
|
||||||
class deque(object):
|
|
||||||
maxlen = 0
|
|
||||||
def __init__(self, iterable=None, maxlen=None):
|
|
||||||
self.iterable = iterable or []
|
|
||||||
def append(self, x): pass
|
|
||||||
def appendleft(self, x): pass
|
|
||||||
def clear(self): pass
|
|
||||||
def count(self, x): return 0
|
|
||||||
def extend(self, iterable): pass
|
|
||||||
def extendleft(self, iterable): pass
|
|
||||||
def pop(self): return self.iterable[0]
|
|
||||||
def popleft(self): return self.iterable[0]
|
|
||||||
def remove(self, value): pass
|
|
||||||
def reverse(self): return reversed(self.iterable)
|
|
||||||
def rotate(self, n=1): return self
|
|
||||||
def __iter__(self): return self
|
|
||||||
def __reversed__(self): return self.iterable[::-1]
|
|
||||||
def __getitem__(self, index): return self.iterable[index]
|
|
||||||
def __setitem__(self, index, value): pass
|
|
||||||
def __delitem__(self, index): pass
|
|
||||||
def __bool__(self): return bool(self.iterable)
|
|
||||||
def __nonzero__(self): return bool(self.iterable)
|
|
||||||
def __contains__(self, o): return o in self.iterable
|
|
||||||
def __len__(self): return len(self.iterable)
|
|
||||||
def __copy__(self): return deque(self.iterable)
|
|
||||||
def copy(self): return deque(self.iterable)
|
|
||||||
def index(self, x, start=0, end=0): return 0
|
|
||||||
def insert(self, x, i): pass
|
|
||||||
def __add__(self, other): pass
|
|
||||||
def __iadd__(self, other): pass
|
|
||||||
def __mul__(self, other): pass
|
|
||||||
def __imul__(self, other): pass
|
|
||||||
def __rmul__(self, other): pass"""
|
|
||||||
return base_deque_class
|
|
||||||
|
|
||||||
|
|
||||||
def _ordered_dict_mock():
|
|
||||||
base_ordered_dict_class = """
|
|
||||||
class OrderedDict(dict):
|
|
||||||
def __reversed__(self): return self[::-1]
|
|
||||||
def move_to_end(self, key, last=False): pass"""
|
|
||||||
return base_ordered_dict_class
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "collections", _collections_transform)
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
import sys
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
PY37 = sys.version_info >= (3, 7)
|
|
||||||
|
|
||||||
if PY37:
|
|
||||||
# Since Python 3.7 Hashing Methods are added
|
|
||||||
# dynamically to globals()
|
|
||||||
|
|
||||||
def _re_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
from collections import namedtuple
|
|
||||||
_Method = namedtuple('_Method', 'name ident salt_chars total_size')
|
|
||||||
|
|
||||||
METHOD_SHA512 = _Method('SHA512', '6', 16, 106)
|
|
||||||
METHOD_SHA256 = _Method('SHA256', '5', 16, 63)
|
|
||||||
METHOD_BLOWFISH = _Method('BLOWFISH', 2, 'b', 22)
|
|
||||||
METHOD_MD5 = _Method('MD5', '1', 8, 34)
|
|
||||||
METHOD_CRYPT = _Method('CRYPT', None, 2, 13)
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "crypt", _re_transform)
|
|
||||||
|
|
@ -1,179 +0,0 @@
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def _curses_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
A_ALTCHARSET = 1
|
|
||||||
A_BLINK = 1
|
|
||||||
A_BOLD = 1
|
|
||||||
A_DIM = 1
|
|
||||||
A_INVIS = 1
|
|
||||||
A_ITALIC = 1
|
|
||||||
A_NORMAL = 1
|
|
||||||
A_PROTECT = 1
|
|
||||||
A_REVERSE = 1
|
|
||||||
A_STANDOUT = 1
|
|
||||||
A_UNDERLINE = 1
|
|
||||||
A_HORIZONTAL = 1
|
|
||||||
A_LEFT = 1
|
|
||||||
A_LOW = 1
|
|
||||||
A_RIGHT = 1
|
|
||||||
A_TOP = 1
|
|
||||||
A_VERTICAL = 1
|
|
||||||
A_CHARTEXT = 1
|
|
||||||
A_ATTRIBUTES = 1
|
|
||||||
A_CHARTEXT = 1
|
|
||||||
A_COLOR = 1
|
|
||||||
KEY_MIN = 1
|
|
||||||
KEY_BREAK = 1
|
|
||||||
KEY_DOWN = 1
|
|
||||||
KEY_UP = 1
|
|
||||||
KEY_LEFT = 1
|
|
||||||
KEY_RIGHT = 1
|
|
||||||
KEY_HOME = 1
|
|
||||||
KEY_BACKSPACE = 1
|
|
||||||
KEY_F0 = 1
|
|
||||||
KEY_Fn = 1
|
|
||||||
KEY_DL = 1
|
|
||||||
KEY_IL = 1
|
|
||||||
KEY_DC = 1
|
|
||||||
KEY_IC = 1
|
|
||||||
KEY_EIC = 1
|
|
||||||
KEY_CLEAR = 1
|
|
||||||
KEY_EOS = 1
|
|
||||||
KEY_EOL = 1
|
|
||||||
KEY_SF = 1
|
|
||||||
KEY_SR = 1
|
|
||||||
KEY_NPAGE = 1
|
|
||||||
KEY_PPAGE = 1
|
|
||||||
KEY_STAB = 1
|
|
||||||
KEY_CTAB = 1
|
|
||||||
KEY_CATAB = 1
|
|
||||||
KEY_ENTER = 1
|
|
||||||
KEY_SRESET = 1
|
|
||||||
KEY_RESET = 1
|
|
||||||
KEY_PRINT = 1
|
|
||||||
KEY_LL = 1
|
|
||||||
KEY_A1 = 1
|
|
||||||
KEY_A3 = 1
|
|
||||||
KEY_B2 = 1
|
|
||||||
KEY_C1 = 1
|
|
||||||
KEY_C3 = 1
|
|
||||||
KEY_BTAB = 1
|
|
||||||
KEY_BEG = 1
|
|
||||||
KEY_CANCEL = 1
|
|
||||||
KEY_CLOSE = 1
|
|
||||||
KEY_COMMAND = 1
|
|
||||||
KEY_COPY = 1
|
|
||||||
KEY_CREATE = 1
|
|
||||||
KEY_END = 1
|
|
||||||
KEY_EXIT = 1
|
|
||||||
KEY_FIND = 1
|
|
||||||
KEY_HELP = 1
|
|
||||||
KEY_MARK = 1
|
|
||||||
KEY_MESSAGE = 1
|
|
||||||
KEY_MOVE = 1
|
|
||||||
KEY_NEXT = 1
|
|
||||||
KEY_OPEN = 1
|
|
||||||
KEY_OPTIONS = 1
|
|
||||||
KEY_PREVIOUS = 1
|
|
||||||
KEY_REDO = 1
|
|
||||||
KEY_REFERENCE = 1
|
|
||||||
KEY_REFRESH = 1
|
|
||||||
KEY_REPLACE = 1
|
|
||||||
KEY_RESTART = 1
|
|
||||||
KEY_RESUME = 1
|
|
||||||
KEY_SAVE = 1
|
|
||||||
KEY_SBEG = 1
|
|
||||||
KEY_SCANCEL = 1
|
|
||||||
KEY_SCOMMAND = 1
|
|
||||||
KEY_SCOPY = 1
|
|
||||||
KEY_SCREATE = 1
|
|
||||||
KEY_SDC = 1
|
|
||||||
KEY_SDL = 1
|
|
||||||
KEY_SELECT = 1
|
|
||||||
KEY_SEND = 1
|
|
||||||
KEY_SEOL = 1
|
|
||||||
KEY_SEXIT = 1
|
|
||||||
KEY_SFIND = 1
|
|
||||||
KEY_SHELP = 1
|
|
||||||
KEY_SHOME = 1
|
|
||||||
KEY_SIC = 1
|
|
||||||
KEY_SLEFT = 1
|
|
||||||
KEY_SMESSAGE = 1
|
|
||||||
KEY_SMOVE = 1
|
|
||||||
KEY_SNEXT = 1
|
|
||||||
KEY_SOPTIONS = 1
|
|
||||||
KEY_SPREVIOUS = 1
|
|
||||||
KEY_SPRINT = 1
|
|
||||||
KEY_SREDO = 1
|
|
||||||
KEY_SREPLACE = 1
|
|
||||||
KEY_SRIGHT = 1
|
|
||||||
KEY_SRSUME = 1
|
|
||||||
KEY_SSAVE = 1
|
|
||||||
KEY_SSUSPEND = 1
|
|
||||||
KEY_SUNDO = 1
|
|
||||||
KEY_SUSPEND = 1
|
|
||||||
KEY_UNDO = 1
|
|
||||||
KEY_MOUSE = 1
|
|
||||||
KEY_RESIZE = 1
|
|
||||||
KEY_MAX = 1
|
|
||||||
ACS_BBSS = 1
|
|
||||||
ACS_BLOCK = 1
|
|
||||||
ACS_BOARD = 1
|
|
||||||
ACS_BSBS = 1
|
|
||||||
ACS_BSSB = 1
|
|
||||||
ACS_BSSS = 1
|
|
||||||
ACS_BTEE = 1
|
|
||||||
ACS_BULLET = 1
|
|
||||||
ACS_CKBOARD = 1
|
|
||||||
ACS_DARROW = 1
|
|
||||||
ACS_DEGREE = 1
|
|
||||||
ACS_DIAMOND = 1
|
|
||||||
ACS_GEQUAL = 1
|
|
||||||
ACS_HLINE = 1
|
|
||||||
ACS_LANTERN = 1
|
|
||||||
ACS_LARROW = 1
|
|
||||||
ACS_LEQUAL = 1
|
|
||||||
ACS_LLCORNER = 1
|
|
||||||
ACS_LRCORNER = 1
|
|
||||||
ACS_LTEE = 1
|
|
||||||
ACS_NEQUAL = 1
|
|
||||||
ACS_PI = 1
|
|
||||||
ACS_PLMINUS = 1
|
|
||||||
ACS_PLUS = 1
|
|
||||||
ACS_RARROW = 1
|
|
||||||
ACS_RTEE = 1
|
|
||||||
ACS_S1 = 1
|
|
||||||
ACS_S3 = 1
|
|
||||||
ACS_S7 = 1
|
|
||||||
ACS_S9 = 1
|
|
||||||
ACS_SBBS = 1
|
|
||||||
ACS_SBSB = 1
|
|
||||||
ACS_SBSS = 1
|
|
||||||
ACS_SSBB = 1
|
|
||||||
ACS_SSBS = 1
|
|
||||||
ACS_SSSB = 1
|
|
||||||
ACS_SSSS = 1
|
|
||||||
ACS_STERLING = 1
|
|
||||||
ACS_TTEE = 1
|
|
||||||
ACS_UARROW = 1
|
|
||||||
ACS_ULCORNER = 1
|
|
||||||
ACS_URCORNER = 1
|
|
||||||
ACS_VLINE = 1
|
|
||||||
COLOR_BLACK = 1
|
|
||||||
COLOR_BLUE = 1
|
|
||||||
COLOR_CYAN = 1
|
|
||||||
COLOR_GREEN = 1
|
|
||||||
COLOR_MAGENTA = 1
|
|
||||||
COLOR_RED = 1
|
|
||||||
COLOR_WHITE = 1
|
|
||||||
COLOR_YELLOW = 1
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "curses", _curses_transform)
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
"""
|
|
||||||
Astroid hook for the dataclasses library
|
|
||||||
"""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
from astroid import MANAGER
|
|
||||||
|
|
||||||
|
|
||||||
DATACLASSES_DECORATORS = frozenset(("dataclasses.dataclass", "dataclass"))
|
|
||||||
|
|
||||||
|
|
||||||
def is_decorated_with_dataclass(node, decorator_names=DATACLASSES_DECORATORS):
|
|
||||||
"""Return True if a decorated node has a `dataclass` decorator applied."""
|
|
||||||
if not node.decorators:
|
|
||||||
return False
|
|
||||||
for decorator_attribute in node.decorators.nodes:
|
|
||||||
if isinstance(decorator_attribute, astroid.Call): # decorator with arguments
|
|
||||||
decorator_attribute = decorator_attribute.func
|
|
||||||
if decorator_attribute.as_string() in decorator_names:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def dataclass_transform(node):
|
|
||||||
"""Rewrite a dataclass to be easily understood by pylint"""
|
|
||||||
|
|
||||||
for assign_node in node.body:
|
|
||||||
if not isinstance(assign_node, (astroid.AnnAssign, astroid.Assign)):
|
|
||||||
continue
|
|
||||||
|
|
||||||
targets = (
|
|
||||||
assign_node.targets
|
|
||||||
if hasattr(assign_node, "targets")
|
|
||||||
else [assign_node.target]
|
|
||||||
)
|
|
||||||
for target in targets:
|
|
||||||
rhs_node = astroid.Unknown(
|
|
||||||
lineno=assign_node.lineno,
|
|
||||||
col_offset=assign_node.col_offset,
|
|
||||||
parent=assign_node,
|
|
||||||
)
|
|
||||||
node.instance_attrs[target.name] = [rhs_node]
|
|
||||||
node.locals[target.name] = [rhs_node]
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
astroid.ClassDef, dataclass_transform, is_decorated_with_dataclass
|
|
||||||
)
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
# Copyright (c) 2015-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2015 raylu <lurayl@gmail.com>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for dateutil"""
|
|
||||||
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
from astroid import MANAGER, register_module_extender
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
|
|
||||||
|
|
||||||
def dateutil_transform():
|
|
||||||
return AstroidBuilder(MANAGER).string_build(
|
|
||||||
textwrap.dedent(
|
|
||||||
"""
|
|
||||||
import datetime
|
|
||||||
def parse(timestr, parserinfo=None, **kwargs):
|
|
||||||
return datetime.datetime()
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
register_module_extender(MANAGER, "dateutil.parser", dateutil_transform)
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
# Copyright (c) 2017-2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
import collections
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def _clone_node_with_lineno(node, parent, lineno):
|
|
||||||
cls = node.__class__
|
|
||||||
other_fields = node._other_fields
|
|
||||||
_astroid_fields = node._astroid_fields
|
|
||||||
init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent}
|
|
||||||
postinit_params = {param: getattr(node, param) for param in _astroid_fields}
|
|
||||||
if other_fields:
|
|
||||||
init_params.update({param: getattr(node, param) for param in other_fields})
|
|
||||||
new_node = cls(**init_params)
|
|
||||||
if hasattr(node, "postinit") and _astroid_fields:
|
|
||||||
for param, child in postinit_params.items():
|
|
||||||
if child and not isinstance(child, collections.Sequence):
|
|
||||||
cloned_child = _clone_node_with_lineno(
|
|
||||||
node=child, lineno=new_node.lineno, parent=new_node
|
|
||||||
)
|
|
||||||
postinit_params[param] = cloned_child
|
|
||||||
new_node.postinit(**postinit_params)
|
|
||||||
return new_node
|
|
||||||
|
|
||||||
|
|
||||||
def _transform_formatted_value(node):
|
|
||||||
if node.value and node.value.lineno == 1:
|
|
||||||
if node.lineno != node.value.lineno:
|
|
||||||
new_node = astroid.FormattedValue(
|
|
||||||
lineno=node.lineno, col_offset=node.col_offset, parent=node.parent
|
|
||||||
)
|
|
||||||
new_value = _clone_node_with_lineno(
|
|
||||||
node=node.value, lineno=node.lineno, parent=new_node
|
|
||||||
)
|
|
||||||
new_node.postinit(value=new_value, format_spec=node.format_spec)
|
|
||||||
return new_node
|
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 6):
|
|
||||||
# TODO: this fix tries to *patch* http://bugs.python.org/issue29051
|
|
||||||
# The problem is that FormattedValue.value, which is a Name node,
|
|
||||||
# has wrong line numbers, usually 1. This creates problems for pylint,
|
|
||||||
# which expects correct line numbers for things such as message control.
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.FormattedValue, _transform_formatted_value
|
|
||||||
)
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
# Copyright (c) 2016, 2018-2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2018 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
|
|
||||||
"""Astroid hooks for understanding functools library module."""
|
|
||||||
from functools import partial
|
|
||||||
from itertools import chain
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
from astroid import arguments
|
|
||||||
from astroid import BoundMethod
|
|
||||||
from astroid import extract_node
|
|
||||||
from astroid import helpers
|
|
||||||
from astroid.interpreter import objectmodel
|
|
||||||
from astroid import MANAGER
|
|
||||||
from astroid import objects
|
|
||||||
|
|
||||||
|
|
||||||
LRU_CACHE = "functools.lru_cache"
|
|
||||||
|
|
||||||
|
|
||||||
class LruWrappedModel(objectmodel.FunctionModel):
|
|
||||||
"""Special attribute model for functions decorated with functools.lru_cache.
|
|
||||||
|
|
||||||
The said decorators patches at decoration time some functions onto
|
|
||||||
the decorated function.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def attr___wrapped__(self):
|
|
||||||
return self._instance
|
|
||||||
|
|
||||||
@property
|
|
||||||
def attr_cache_info(self):
|
|
||||||
cache_info = extract_node(
|
|
||||||
"""
|
|
||||||
from functools import _CacheInfo
|
|
||||||
_CacheInfo(0, 0, 0, 0)
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
class CacheInfoBoundMethod(BoundMethod):
|
|
||||||
def infer_call_result(self, caller, context=None):
|
|
||||||
yield helpers.safe_infer(cache_info)
|
|
||||||
|
|
||||||
return CacheInfoBoundMethod(proxy=self._instance, bound=self._instance)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def attr_cache_clear(self):
|
|
||||||
node = extract_node("""def cache_clear(self): pass""")
|
|
||||||
return BoundMethod(proxy=node, bound=self._instance.parent.scope())
|
|
||||||
|
|
||||||
|
|
||||||
def _transform_lru_cache(node, context=None):
|
|
||||||
# TODO: this is not ideal, since the node should be immutable,
|
|
||||||
# but due to https://github.com/PyCQA/astroid/issues/354,
|
|
||||||
# there's not much we can do now.
|
|
||||||
# Replacing the node would work partially, because,
|
|
||||||
# in pylint, the old node would still be available, leading
|
|
||||||
# to spurious false positives.
|
|
||||||
node.special_attributes = LruWrappedModel()(node)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def _functools_partial_inference(node, context=None):
|
|
||||||
call = arguments.CallSite.from_call(node, context=context)
|
|
||||||
number_of_positional = len(call.positional_arguments)
|
|
||||||
if number_of_positional < 1:
|
|
||||||
raise astroid.UseInferenceDefault(
|
|
||||||
"functools.partial takes at least one argument"
|
|
||||||
)
|
|
||||||
if number_of_positional == 1 and not call.keyword_arguments:
|
|
||||||
raise astroid.UseInferenceDefault(
|
|
||||||
"functools.partial needs at least to have some filled arguments"
|
|
||||||
)
|
|
||||||
|
|
||||||
partial_function = call.positional_arguments[0]
|
|
||||||
try:
|
|
||||||
inferred_wrapped_function = next(partial_function.infer(context=context))
|
|
||||||
except astroid.InferenceError as exc:
|
|
||||||
raise astroid.UseInferenceDefault from exc
|
|
||||||
if inferred_wrapped_function is astroid.Uninferable:
|
|
||||||
raise astroid.UseInferenceDefault("Cannot infer the wrapped function")
|
|
||||||
if not isinstance(inferred_wrapped_function, astroid.FunctionDef):
|
|
||||||
raise astroid.UseInferenceDefault("The wrapped function is not a function")
|
|
||||||
|
|
||||||
# Determine if the passed keywords into the callsite are supported
|
|
||||||
# by the wrapped function.
|
|
||||||
function_parameters = chain(
|
|
||||||
inferred_wrapped_function.args.args or (),
|
|
||||||
inferred_wrapped_function.args.posonlyargs or (),
|
|
||||||
inferred_wrapped_function.args.kwonlyargs or (),
|
|
||||||
)
|
|
||||||
parameter_names = set(
|
|
||||||
param.name
|
|
||||||
for param in function_parameters
|
|
||||||
if isinstance(param, astroid.AssignName)
|
|
||||||
)
|
|
||||||
if set(call.keyword_arguments) - parameter_names:
|
|
||||||
raise astroid.UseInferenceDefault(
|
|
||||||
"wrapped function received unknown parameters"
|
|
||||||
)
|
|
||||||
|
|
||||||
partial_function = objects.PartialFunction(
|
|
||||||
call,
|
|
||||||
name=inferred_wrapped_function.name,
|
|
||||||
doc=inferred_wrapped_function.doc,
|
|
||||||
lineno=inferred_wrapped_function.lineno,
|
|
||||||
col_offset=inferred_wrapped_function.col_offset,
|
|
||||||
parent=inferred_wrapped_function.parent,
|
|
||||||
)
|
|
||||||
partial_function.postinit(
|
|
||||||
args=inferred_wrapped_function.args,
|
|
||||||
body=inferred_wrapped_function.body,
|
|
||||||
decorators=inferred_wrapped_function.decorators,
|
|
||||||
returns=inferred_wrapped_function.returns,
|
|
||||||
type_comment_returns=inferred_wrapped_function.type_comment_returns,
|
|
||||||
type_comment_args=inferred_wrapped_function.type_comment_args,
|
|
||||||
)
|
|
||||||
return iter((partial_function,))
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_lru_cache(node):
|
|
||||||
"""Check if the given function node is decorated with lru_cache."""
|
|
||||||
if not node.decorators:
|
|
||||||
return False
|
|
||||||
for decorator in node.decorators.nodes:
|
|
||||||
if not isinstance(decorator, astroid.Call):
|
|
||||||
continue
|
|
||||||
if _looks_like_functools_member(decorator, "lru_cache"):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_functools_member(node, member):
|
|
||||||
"""Check if the given Call node is a functools.partial call"""
|
|
||||||
if isinstance(node.func, astroid.Name):
|
|
||||||
return node.func.name == member
|
|
||||||
elif isinstance(node.func, astroid.Attribute):
|
|
||||||
return (
|
|
||||||
node.func.attrname == member
|
|
||||||
and isinstance(node.func.expr, astroid.Name)
|
|
||||||
and node.func.expr.name == "functools"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_looks_like_partial = partial(_looks_like_functools_member, member="partial")
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
astroid.FunctionDef, _transform_lru_cache, _looks_like_lru_cache
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
astroid.Call,
|
|
||||||
astroid.inference_tip(_functools_partial_inference),
|
|
||||||
_looks_like_partial,
|
|
||||||
)
|
|
||||||
|
|
@ -1,253 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2014 Google, Inc.
|
|
||||||
# Copyright (c) 2014 Cole Robinson <crobinso@redhat.com>
|
|
||||||
# Copyright (c) 2015-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2015 David Shea <dshea@redhat.com>
|
|
||||||
# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net>
|
|
||||||
# Copyright (c) 2016 Giuseppe Scrivano <gscrivan@redhat.com>
|
|
||||||
# Copyright (c) 2018 Christoph Reiter <reiter.christoph@gmail.com>
|
|
||||||
# Copyright (c) 2019 Philipp Hörist <philipp@hoerist.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for the Python 2 GObject introspection bindings.
|
|
||||||
|
|
||||||
Helps with understanding everything imported from 'gi.repository'
|
|
||||||
"""
|
|
||||||
|
|
||||||
import inspect
|
|
||||||
import itertools
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from astroid import MANAGER, AstroidBuildingError, nodes
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
|
|
||||||
|
|
||||||
_inspected_modules = {}
|
|
||||||
|
|
||||||
_identifier_re = r"^[A-Za-z_]\w*$"
|
|
||||||
|
|
||||||
_special_methods = frozenset(
|
|
||||||
{
|
|
||||||
"__lt__",
|
|
||||||
"__le__",
|
|
||||||
"__eq__",
|
|
||||||
"__ne__",
|
|
||||||
"__ge__",
|
|
||||||
"__gt__",
|
|
||||||
"__iter__",
|
|
||||||
"__getitem__",
|
|
||||||
"__setitem__",
|
|
||||||
"__delitem__",
|
|
||||||
"__len__",
|
|
||||||
"__bool__",
|
|
||||||
"__nonzero__",
|
|
||||||
"__next__",
|
|
||||||
"__str__",
|
|
||||||
"__len__",
|
|
||||||
"__contains__",
|
|
||||||
"__enter__",
|
|
||||||
"__exit__",
|
|
||||||
"__repr__",
|
|
||||||
"__getattr__",
|
|
||||||
"__setattr__",
|
|
||||||
"__delattr__",
|
|
||||||
"__del__",
|
|
||||||
"__hash__",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _gi_build_stub(parent):
|
|
||||||
"""
|
|
||||||
Inspect the passed module recursively and build stubs for functions,
|
|
||||||
classes, etc.
|
|
||||||
"""
|
|
||||||
classes = {}
|
|
||||||
functions = {}
|
|
||||||
constants = {}
|
|
||||||
methods = {}
|
|
||||||
for name in dir(parent):
|
|
||||||
if name.startswith("__") and name not in _special_methods:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Check if this is a valid name in python
|
|
||||||
if not re.match(_identifier_re, name):
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
obj = getattr(parent, name)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if inspect.isclass(obj):
|
|
||||||
classes[name] = obj
|
|
||||||
elif inspect.isfunction(obj) or inspect.isbuiltin(obj):
|
|
||||||
functions[name] = obj
|
|
||||||
elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
|
|
||||||
methods[name] = obj
|
|
||||||
elif (
|
|
||||||
str(obj).startswith("<flags")
|
|
||||||
or str(obj).startswith("<enum ")
|
|
||||||
or str(obj).startswith("<GType ")
|
|
||||||
or inspect.isdatadescriptor(obj)
|
|
||||||
):
|
|
||||||
constants[name] = 0
|
|
||||||
elif isinstance(obj, (int, str)):
|
|
||||||
constants[name] = obj
|
|
||||||
elif callable(obj):
|
|
||||||
# Fall back to a function for anything callable
|
|
||||||
functions[name] = obj
|
|
||||||
else:
|
|
||||||
# Assume everything else is some manner of constant
|
|
||||||
constants[name] = 0
|
|
||||||
|
|
||||||
ret = ""
|
|
||||||
|
|
||||||
if constants:
|
|
||||||
ret += "# %s constants\n\n" % parent.__name__
|
|
||||||
for name in sorted(constants):
|
|
||||||
if name[0].isdigit():
|
|
||||||
# GDK has some busted constant names like
|
|
||||||
# Gdk.EventType.2BUTTON_PRESS
|
|
||||||
continue
|
|
||||||
|
|
||||||
val = constants[name]
|
|
||||||
|
|
||||||
strval = str(val)
|
|
||||||
if isinstance(val, str):
|
|
||||||
strval = '"%s"' % str(val).replace("\\", "\\\\")
|
|
||||||
ret += "%s = %s\n" % (name, strval)
|
|
||||||
|
|
||||||
if ret:
|
|
||||||
ret += "\n\n"
|
|
||||||
if functions:
|
|
||||||
ret += "# %s functions\n\n" % parent.__name__
|
|
||||||
for name in sorted(functions):
|
|
||||||
ret += "def %s(*args, **kwargs):\n" % name
|
|
||||||
ret += " pass\n"
|
|
||||||
|
|
||||||
if ret:
|
|
||||||
ret += "\n\n"
|
|
||||||
if methods:
|
|
||||||
ret += "# %s methods\n\n" % parent.__name__
|
|
||||||
for name in sorted(methods):
|
|
||||||
ret += "def %s(self, *args, **kwargs):\n" % name
|
|
||||||
ret += " pass\n"
|
|
||||||
|
|
||||||
if ret:
|
|
||||||
ret += "\n\n"
|
|
||||||
if classes:
|
|
||||||
ret += "# %s classes\n\n" % parent.__name__
|
|
||||||
for name, obj in sorted(classes.items()):
|
|
||||||
base = "object"
|
|
||||||
if issubclass(obj, Exception):
|
|
||||||
base = "Exception"
|
|
||||||
ret += "class %s(%s):\n" % (name, base)
|
|
||||||
|
|
||||||
classret = _gi_build_stub(obj)
|
|
||||||
if not classret:
|
|
||||||
classret = "pass\n"
|
|
||||||
|
|
||||||
for line in classret.splitlines():
|
|
||||||
ret += " " + line + "\n"
|
|
||||||
ret += "\n"
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def _import_gi_module(modname):
|
|
||||||
# we only consider gi.repository submodules
|
|
||||||
if not modname.startswith("gi.repository."):
|
|
||||||
raise AstroidBuildingError(modname=modname)
|
|
||||||
# build astroid representation unless we already tried so
|
|
||||||
if modname not in _inspected_modules:
|
|
||||||
modnames = [modname]
|
|
||||||
optional_modnames = []
|
|
||||||
|
|
||||||
# GLib and GObject may have some special case handling
|
|
||||||
# in pygobject that we need to cope with. However at
|
|
||||||
# least as of pygobject3-3.13.91 the _glib module doesn't
|
|
||||||
# exist anymore, so if treat these modules as optional.
|
|
||||||
if modname == "gi.repository.GLib":
|
|
||||||
optional_modnames.append("gi._glib")
|
|
||||||
elif modname == "gi.repository.GObject":
|
|
||||||
optional_modnames.append("gi._gobject")
|
|
||||||
|
|
||||||
try:
|
|
||||||
modcode = ""
|
|
||||||
for m in itertools.chain(modnames, optional_modnames):
|
|
||||||
try:
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
# Just inspecting the code can raise gi deprecation
|
|
||||||
# warnings, so ignore them.
|
|
||||||
try:
|
|
||||||
from gi import PyGIDeprecationWarning, PyGIWarning
|
|
||||||
|
|
||||||
warnings.simplefilter("ignore", PyGIDeprecationWarning)
|
|
||||||
warnings.simplefilter("ignore", PyGIWarning)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
__import__(m)
|
|
||||||
modcode += _gi_build_stub(sys.modules[m])
|
|
||||||
except ImportError:
|
|
||||||
if m not in optional_modnames:
|
|
||||||
raise
|
|
||||||
except ImportError:
|
|
||||||
astng = _inspected_modules[modname] = None
|
|
||||||
else:
|
|
||||||
astng = AstroidBuilder(MANAGER).string_build(modcode, modname)
|
|
||||||
_inspected_modules[modname] = astng
|
|
||||||
else:
|
|
||||||
astng = _inspected_modules[modname]
|
|
||||||
if astng is None:
|
|
||||||
raise AstroidBuildingError(modname=modname)
|
|
||||||
return astng
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_require_version(node):
|
|
||||||
# Return whether this looks like a call to gi.require_version(<name>, <version>)
|
|
||||||
# Only accept function calls with two constant arguments
|
|
||||||
if len(node.args) != 2:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not all(isinstance(arg, nodes.Const) for arg in node.args):
|
|
||||||
return False
|
|
||||||
|
|
||||||
func = node.func
|
|
||||||
if isinstance(func, nodes.Attribute):
|
|
||||||
if func.attrname != "require_version":
|
|
||||||
return False
|
|
||||||
if isinstance(func.expr, nodes.Name) and func.expr.name == "gi":
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
if isinstance(func, nodes.Name):
|
|
||||||
return func.name == "require_version"
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _register_require_version(node):
|
|
||||||
# Load the gi.require_version locally
|
|
||||||
try:
|
|
||||||
import gi
|
|
||||||
|
|
||||||
gi.require_version(node.args[0].value, node.args[1].value)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_failed_import_hook(_import_gi_module)
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.Call, _register_require_version, _looks_like_require_version
|
|
||||||
)
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2018 David Poirier <david-poirier-csn@users.noreply.github.com>
|
|
||||||
# Copyright (c) 2018 wgehalo <wgehalo@gmail.com>
|
|
||||||
# Copyright (c) 2018 Ioana Tagirta <ioana.tagirta@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
PY36 = sys.version_info >= (3, 6)
|
|
||||||
|
|
||||||
|
|
||||||
def _hashlib_transform():
|
|
||||||
signature = "value=''"
|
|
||||||
template = """
|
|
||||||
class %(name)s(object):
|
|
||||||
def __init__(self, %(signature)s): pass
|
|
||||||
def digest(self):
|
|
||||||
return %(digest)s
|
|
||||||
def copy(self):
|
|
||||||
return self
|
|
||||||
def update(self, value): pass
|
|
||||||
def hexdigest(self):
|
|
||||||
return ''
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
return %(name)r
|
|
||||||
@property
|
|
||||||
def block_size(self):
|
|
||||||
return 1
|
|
||||||
@property
|
|
||||||
def digest_size(self):
|
|
||||||
return 1
|
|
||||||
"""
|
|
||||||
algorithms_with_signature = dict.fromkeys(
|
|
||||||
["md5", "sha1", "sha224", "sha256", "sha384", "sha512"], signature
|
|
||||||
)
|
|
||||||
if PY36:
|
|
||||||
blake2b_signature = "data=b'', *, digest_size=64, key=b'', salt=b'', \
|
|
||||||
person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \
|
|
||||||
node_depth=0, inner_size=0, last_node=False"
|
|
||||||
blake2s_signature = "data=b'', *, digest_size=32, key=b'', salt=b'', \
|
|
||||||
person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \
|
|
||||||
node_depth=0, inner_size=0, last_node=False"
|
|
||||||
new_algorithms = dict.fromkeys(
|
|
||||||
["sha3_224", "sha3_256", "sha3_384", "sha3_512", "shake_128", "shake_256"],
|
|
||||||
signature,
|
|
||||||
)
|
|
||||||
algorithms_with_signature.update(new_algorithms)
|
|
||||||
algorithms_with_signature.update(
|
|
||||||
{"blake2b": blake2b_signature, "blake2s": blake2s_signature}
|
|
||||||
)
|
|
||||||
classes = "".join(
|
|
||||||
template
|
|
||||||
% {
|
|
||||||
"name": hashfunc,
|
|
||||||
"digest": 'b""' if six.PY3 else '""',
|
|
||||||
"signature": signature,
|
|
||||||
}
|
|
||||||
for hashfunc, signature in algorithms_with_signature.items()
|
|
||||||
)
|
|
||||||
return astroid.parse(classes)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "hashlib", _hashlib_transform)
|
|
||||||
|
|
@ -1,211 +0,0 @@
|
||||||
# Copyright (c) 2018-2019 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid brain hints for some of the `http` module."""
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
|
|
||||||
|
|
||||||
def _http_transform():
|
|
||||||
code = textwrap.dedent(
|
|
||||||
"""
|
|
||||||
from collections import namedtuple
|
|
||||||
_HTTPStatus = namedtuple('_HTTPStatus', 'value phrase description')
|
|
||||||
|
|
||||||
class HTTPStatus:
|
|
||||||
|
|
||||||
@property
|
|
||||||
def phrase(self):
|
|
||||||
return ""
|
|
||||||
@property
|
|
||||||
def value(self):
|
|
||||||
return 0
|
|
||||||
@property
|
|
||||||
def description(self):
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# informational
|
|
||||||
CONTINUE = _HTTPStatus(100, 'Continue', 'Request received, please continue')
|
|
||||||
SWITCHING_PROTOCOLS = _HTTPStatus(101, 'Switching Protocols',
|
|
||||||
'Switching to new protocol; obey Upgrade header')
|
|
||||||
PROCESSING = _HTTPStatus(102, 'Processing', '')
|
|
||||||
OK = _HTTPStatus(200, 'OK', 'Request fulfilled, document follows')
|
|
||||||
CREATED = _HTTPStatus(201, 'Created', 'Document created, URL follows')
|
|
||||||
ACCEPTED = _HTTPStatus(202, 'Accepted',
|
|
||||||
'Request accepted, processing continues off-line')
|
|
||||||
NON_AUTHORITATIVE_INFORMATION = _HTTPStatus(203,
|
|
||||||
'Non-Authoritative Information', 'Request fulfilled from cache')
|
|
||||||
NO_CONTENT = _HTTPStatus(204, 'No Content', 'Request fulfilled, nothing follows')
|
|
||||||
RESET_CONTENT =_HTTPStatus(205, 'Reset Content', 'Clear input form for further input')
|
|
||||||
PARTIAL_CONTENT = _HTTPStatus(206, 'Partial Content', 'Partial content follows')
|
|
||||||
MULTI_STATUS = _HTTPStatus(207, 'Multi-Status', '')
|
|
||||||
ALREADY_REPORTED = _HTTPStatus(208, 'Already Reported', '')
|
|
||||||
IM_USED = _HTTPStatus(226, 'IM Used', '')
|
|
||||||
MULTIPLE_CHOICES = _HTTPStatus(300, 'Multiple Choices',
|
|
||||||
'Object has several resources -- see URI list')
|
|
||||||
MOVED_PERMANENTLY = _HTTPStatus(301, 'Moved Permanently',
|
|
||||||
'Object moved permanently -- see URI list')
|
|
||||||
FOUND = _HTTPStatus(302, 'Found', 'Object moved temporarily -- see URI list')
|
|
||||||
SEE_OTHER = _HTTPStatus(303, 'See Other', 'Object moved -- see Method and URL list')
|
|
||||||
NOT_MODIFIED = _HTTPStatus(304, 'Not Modified',
|
|
||||||
'Document has not changed since given time')
|
|
||||||
USE_PROXY = _HTTPStatus(305, 'Use Proxy',
|
|
||||||
'You must use proxy specified in Location to access this resource')
|
|
||||||
TEMPORARY_REDIRECT = _HTTPStatus(307, 'Temporary Redirect',
|
|
||||||
'Object moved temporarily -- see URI list')
|
|
||||||
PERMANENT_REDIRECT = _HTTPStatus(308, 'Permanent Redirect',
|
|
||||||
'Object moved permanently -- see URI list')
|
|
||||||
BAD_REQUEST = _HTTPStatus(400, 'Bad Request',
|
|
||||||
'Bad request syntax or unsupported method')
|
|
||||||
UNAUTHORIZED = _HTTPStatus(401, 'Unauthorized',
|
|
||||||
'No permission -- see authorization schemes')
|
|
||||||
PAYMENT_REQUIRED = _HTTPStatus(402, 'Payment Required',
|
|
||||||
'No payment -- see charging schemes')
|
|
||||||
FORBIDDEN = _HTTPStatus(403, 'Forbidden',
|
|
||||||
'Request forbidden -- authorization will not help')
|
|
||||||
NOT_FOUND = _HTTPStatus(404, 'Not Found',
|
|
||||||
'Nothing matches the given URI')
|
|
||||||
METHOD_NOT_ALLOWED = _HTTPStatus(405, 'Method Not Allowed',
|
|
||||||
'Specified method is invalid for this resource')
|
|
||||||
NOT_ACCEPTABLE = _HTTPStatus(406, 'Not Acceptable',
|
|
||||||
'URI not available in preferred format')
|
|
||||||
PROXY_AUTHENTICATION_REQUIRED = _HTTPStatus(407,
|
|
||||||
'Proxy Authentication Required',
|
|
||||||
'You must authenticate with this proxy before proceeding')
|
|
||||||
REQUEST_TIMEOUT = _HTTPStatus(408, 'Request Timeout',
|
|
||||||
'Request timed out; try again later')
|
|
||||||
CONFLICT = _HTTPStatus(409, 'Conflict', 'Request conflict')
|
|
||||||
GONE = _HTTPStatus(410, 'Gone',
|
|
||||||
'URI no longer exists and has been permanently removed')
|
|
||||||
LENGTH_REQUIRED = _HTTPStatus(411, 'Length Required',
|
|
||||||
'Client must specify Content-Length')
|
|
||||||
PRECONDITION_FAILED = _HTTPStatus(412, 'Precondition Failed',
|
|
||||||
'Precondition in headers is false')
|
|
||||||
REQUEST_ENTITY_TOO_LARGE = _HTTPStatus(413, 'Request Entity Too Large',
|
|
||||||
'Entity is too large')
|
|
||||||
REQUEST_URI_TOO_LONG = _HTTPStatus(414, 'Request-URI Too Long',
|
|
||||||
'URI is too long')
|
|
||||||
UNSUPPORTED_MEDIA_TYPE = _HTTPStatus(415, 'Unsupported Media Type',
|
|
||||||
'Entity body in unsupported format')
|
|
||||||
REQUESTED_RANGE_NOT_SATISFIABLE = _HTTPStatus(416,
|
|
||||||
'Requested Range Not Satisfiable',
|
|
||||||
'Cannot satisfy request range')
|
|
||||||
EXPECTATION_FAILED = _HTTPStatus(417, 'Expectation Failed',
|
|
||||||
'Expect condition could not be satisfied')
|
|
||||||
MISDIRECTED_REQUEST = _HTTPStatus(421, 'Misdirected Request',
|
|
||||||
'Server is not able to produce a response')
|
|
||||||
UNPROCESSABLE_ENTITY = _HTTPStatus(422, 'Unprocessable Entity')
|
|
||||||
LOCKED = _HTTPStatus(423, 'Locked')
|
|
||||||
FAILED_DEPENDENCY = _HTTPStatus(424, 'Failed Dependency')
|
|
||||||
UPGRADE_REQUIRED = _HTTPStatus(426, 'Upgrade Required')
|
|
||||||
PRECONDITION_REQUIRED = _HTTPStatus(428, 'Precondition Required',
|
|
||||||
'The origin server requires the request to be conditional')
|
|
||||||
TOO_MANY_REQUESTS = _HTTPStatus(429, 'Too Many Requests',
|
|
||||||
'The user has sent too many requests in '
|
|
||||||
'a given amount of time ("rate limiting")')
|
|
||||||
REQUEST_HEADER_FIELDS_TOO_LARGE = _HTTPStatus(431,
|
|
||||||
'Request Header Fields Too Large',
|
|
||||||
'The server is unwilling to process the request because its header '
|
|
||||||
'fields are too large')
|
|
||||||
UNAVAILABLE_FOR_LEGAL_REASONS = _HTTPStatus(451,
|
|
||||||
'Unavailable For Legal Reasons',
|
|
||||||
'The server is denying access to the '
|
|
||||||
'resource as a consequence of a legal demand')
|
|
||||||
INTERNAL_SERVER_ERROR = _HTTPStatus(500, 'Internal Server Error',
|
|
||||||
'Server got itself in trouble')
|
|
||||||
NOT_IMPLEMENTED = _HTTPStatus(501, 'Not Implemented',
|
|
||||||
'Server does not support this operation')
|
|
||||||
BAD_GATEWAY = _HTTPStatus(502, 'Bad Gateway',
|
|
||||||
'Invalid responses from another server/proxy')
|
|
||||||
SERVICE_UNAVAILABLE = _HTTPStatus(503, 'Service Unavailable',
|
|
||||||
'The server cannot process the request due to a high load')
|
|
||||||
GATEWAY_TIMEOUT = _HTTPStatus(504, 'Gateway Timeout',
|
|
||||||
'The gateway server did not receive a timely response')
|
|
||||||
HTTP_VERSION_NOT_SUPPORTED = _HTTPStatus(505, 'HTTP Version Not Supported',
|
|
||||||
'Cannot fulfill request')
|
|
||||||
VARIANT_ALSO_NEGOTIATES = _HTTPStatus(506, 'Variant Also Negotiates')
|
|
||||||
INSUFFICIENT_STORAGE = _HTTPStatus(507, 'Insufficient Storage')
|
|
||||||
LOOP_DETECTED = _HTTPStatus(508, 'Loop Detected')
|
|
||||||
NOT_EXTENDED = _HTTPStatus(510, 'Not Extended')
|
|
||||||
NETWORK_AUTHENTICATION_REQUIRED = _HTTPStatus(511,
|
|
||||||
'Network Authentication Required',
|
|
||||||
'The client needs to authenticate to gain network access')
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
return AstroidBuilder(astroid.MANAGER).string_build(code)
|
|
||||||
|
|
||||||
|
|
||||||
def _http_client_transform():
|
|
||||||
return AstroidBuilder(astroid.MANAGER).string_build(
|
|
||||||
textwrap.dedent(
|
|
||||||
"""
|
|
||||||
from http import HTTPStatus
|
|
||||||
|
|
||||||
CONTINUE = HTTPStatus.CONTINUE
|
|
||||||
SWITCHING_PROTOCOLS = HTTPStatus.SWITCHING_PROTOCOLS
|
|
||||||
PROCESSING = HTTPStatus.PROCESSING
|
|
||||||
OK = HTTPStatus.OK
|
|
||||||
CREATED = HTTPStatus.CREATED
|
|
||||||
ACCEPTED = HTTPStatus.ACCEPTED
|
|
||||||
NON_AUTHORITATIVE_INFORMATION = HTTPStatus.NON_AUTHORITATIVE_INFORMATION
|
|
||||||
NO_CONTENT = HTTPStatus.NO_CONTENT
|
|
||||||
RESET_CONTENT = HTTPStatus.RESET_CONTENT
|
|
||||||
PARTIAL_CONTENT = HTTPStatus.PARTIAL_CONTENT
|
|
||||||
MULTI_STATUS = HTTPStatus.MULTI_STATUS
|
|
||||||
ALREADY_REPORTED = HTTPStatus.ALREADY_REPORTED
|
|
||||||
IM_USED = HTTPStatus.IM_USED
|
|
||||||
MULTIPLE_CHOICES = HTTPStatus.MULTIPLE_CHOICES
|
|
||||||
MOVED_PERMANENTLY = HTTPStatus.MOVED_PERMANENTLY
|
|
||||||
FOUND = HTTPStatus.FOUND
|
|
||||||
SEE_OTHER = HTTPStatus.SEE_OTHER
|
|
||||||
NOT_MODIFIED = HTTPStatus.NOT_MODIFIED
|
|
||||||
USE_PROXY = HTTPStatus.USE_PROXY
|
|
||||||
TEMPORARY_REDIRECT = HTTPStatus.TEMPORARY_REDIRECT
|
|
||||||
PERMANENT_REDIRECT = HTTPStatus.PERMANENT_REDIRECT
|
|
||||||
BAD_REQUEST = HTTPStatus.BAD_REQUEST
|
|
||||||
UNAUTHORIZED = HTTPStatus.UNAUTHORIZED
|
|
||||||
PAYMENT_REQUIRED = HTTPStatus.PAYMENT_REQUIRED
|
|
||||||
FORBIDDEN = HTTPStatus.FORBIDDEN
|
|
||||||
NOT_FOUND = HTTPStatus.NOT_FOUND
|
|
||||||
METHOD_NOT_ALLOWED = HTTPStatus.METHOD_NOT_ALLOWED
|
|
||||||
NOT_ACCEPTABLE = HTTPStatus.NOT_ACCEPTABLE
|
|
||||||
PROXY_AUTHENTICATION_REQUIRED = HTTPStatus.PROXY_AUTHENTICATION_REQUIRED
|
|
||||||
REQUEST_TIMEOUT = HTTPStatus.REQUEST_TIMEOUT
|
|
||||||
CONFLICT = HTTPStatus.CONFLICT
|
|
||||||
GONE = HTTPStatus.GONE
|
|
||||||
LENGTH_REQUIRED = HTTPStatus.LENGTH_REQUIRED
|
|
||||||
PRECONDITION_FAILED = HTTPStatus.PRECONDITION_FAILED
|
|
||||||
REQUEST_ENTITY_TOO_LARGE = HTTPStatus.REQUEST_ENTITY_TOO_LARGE
|
|
||||||
REQUEST_URI_TOO_LONG = HTTPStatus.REQUEST_URI_TOO_LONG
|
|
||||||
UNSUPPORTED_MEDIA_TYPE = HTTPStatus.UNSUPPORTED_MEDIA_TYPE
|
|
||||||
REQUESTED_RANGE_NOT_SATISFIABLE = HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE
|
|
||||||
EXPECTATION_FAILED = HTTPStatus.EXPECTATION_FAILED
|
|
||||||
UNPROCESSABLE_ENTITY = HTTPStatus.UNPROCESSABLE_ENTITY
|
|
||||||
LOCKED = HTTPStatus.LOCKED
|
|
||||||
FAILED_DEPENDENCY = HTTPStatus.FAILED_DEPENDENCY
|
|
||||||
UPGRADE_REQUIRED = HTTPStatus.UPGRADE_REQUIRED
|
|
||||||
PRECONDITION_REQUIRED = HTTPStatus.PRECONDITION_REQUIRED
|
|
||||||
TOO_MANY_REQUESTS = HTTPStatus.TOO_MANY_REQUESTS
|
|
||||||
REQUEST_HEADER_FIELDS_TOO_LARGE = HTTPStatus.REQUEST_HEADER_FIELDS_TOO_LARGE
|
|
||||||
INTERNAL_SERVER_ERROR = HTTPStatus.INTERNAL_SERVER_ERROR
|
|
||||||
NOT_IMPLEMENTED = HTTPStatus.NOT_IMPLEMENTED
|
|
||||||
BAD_GATEWAY = HTTPStatus.BAD_GATEWAY
|
|
||||||
SERVICE_UNAVAILABLE = HTTPStatus.SERVICE_UNAVAILABLE
|
|
||||||
GATEWAY_TIMEOUT = HTTPStatus.GATEWAY_TIMEOUT
|
|
||||||
HTTP_VERSION_NOT_SUPPORTED = HTTPStatus.HTTP_VERSION_NOT_SUPPORTED
|
|
||||||
VARIANT_ALSO_NEGOTIATES = HTTPStatus.VARIANT_ALSO_NEGOTIATES
|
|
||||||
INSUFFICIENT_STORAGE = HTTPStatus.INSUFFICIENT_STORAGE
|
|
||||||
LOOP_DETECTED = HTTPStatus.LOOP_DETECTED
|
|
||||||
NOT_EXTENDED = HTTPStatus.NOT_EXTENDED
|
|
||||||
NETWORK_AUTHENTICATION_REQUIRED = HTTPStatus.NETWORK_AUTHENTICATION_REQUIRED
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "http", _http_transform)
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "http.client", _http_client_transform)
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid brain hints for some of the _io C objects."""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
BUFFERED = {"BufferedWriter", "BufferedReader"}
|
|
||||||
TextIOWrapper = "TextIOWrapper"
|
|
||||||
FileIO = "FileIO"
|
|
||||||
BufferedWriter = "BufferedWriter"
|
|
||||||
|
|
||||||
|
|
||||||
def _generic_io_transform(node, name, cls):
|
|
||||||
"""Transform the given name, by adding the given *class* as a member of the node."""
|
|
||||||
|
|
||||||
io_module = astroid.MANAGER.ast_from_module_name("_io")
|
|
||||||
attribute_object = io_module[cls]
|
|
||||||
instance = attribute_object.instantiate_class()
|
|
||||||
node.locals[name] = [instance]
|
|
||||||
|
|
||||||
|
|
||||||
def _transform_text_io_wrapper(node):
|
|
||||||
# This is not always correct, since it can vary with the type of the descriptor,
|
|
||||||
# being stdout, stderr or stdin. But we cannot get access to the name of the
|
|
||||||
# stream, which is why we are using the BufferedWriter class as a default
|
|
||||||
# value
|
|
||||||
return _generic_io_transform(node, name="buffer", cls=BufferedWriter)
|
|
||||||
|
|
||||||
|
|
||||||
def _transform_buffered(node):
|
|
||||||
return _generic_io_transform(node, name="raw", cls=FileIO)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.ClassDef, _transform_buffered, lambda node: node.name in BUFFERED
|
|
||||||
)
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.ClassDef,
|
|
||||||
_transform_text_io_wrapper,
|
|
||||||
lambda node: node.name == TextIOWrapper,
|
|
||||||
)
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
# Copyright (c) 2012-2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2014 Google, Inc.
|
|
||||||
# Copyright (c) 2015-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
from astroid import MANAGER, register_module_extender
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
|
|
||||||
|
|
||||||
def mechanize_transform():
|
|
||||||
return AstroidBuilder(MANAGER).string_build(
|
|
||||||
"""
|
|
||||||
|
|
||||||
class Browser(object):
|
|
||||||
def open(self, url, data=None, timeout=None):
|
|
||||||
return None
|
|
||||||
def open_novisit(self, url, data=None, timeout=None):
|
|
||||||
return None
|
|
||||||
def open_local_file(self, filename):
|
|
||||||
return None
|
|
||||||
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
register_module_extender(MANAGER, "mechanize", mechanize_transform)
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
from astroid import exceptions
|
|
||||||
|
|
||||||
|
|
||||||
def _multiprocessing_transform():
|
|
||||||
module = astroid.parse(
|
|
||||||
"""
|
|
||||||
from multiprocessing.managers import SyncManager
|
|
||||||
def Manager():
|
|
||||||
return SyncManager()
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
# Multiprocessing uses a getattr lookup inside contexts,
|
|
||||||
# in order to get the attributes they need. Since it's extremely
|
|
||||||
# dynamic, we use this approach to fake it.
|
|
||||||
node = astroid.parse(
|
|
||||||
"""
|
|
||||||
from multiprocessing.context import DefaultContext, BaseContext
|
|
||||||
default = DefaultContext()
|
|
||||||
base = BaseContext()
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
context = next(node["default"].infer())
|
|
||||||
base = next(node["base"].infer())
|
|
||||||
except exceptions.InferenceError:
|
|
||||||
return module
|
|
||||||
|
|
||||||
for node in (context, base):
|
|
||||||
for key, value in node.locals.items():
|
|
||||||
if key.startswith("_"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
value = value[0]
|
|
||||||
if isinstance(value, astroid.FunctionDef):
|
|
||||||
# We need to rebound this, since otherwise
|
|
||||||
# it will have an extra argument (self).
|
|
||||||
value = astroid.BoundMethod(value, node)
|
|
||||||
module[key] = value
|
|
||||||
return module
|
|
||||||
|
|
||||||
|
|
||||||
def _multiprocessing_managers_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
import array
|
|
||||||
import threading
|
|
||||||
import multiprocessing.pool as pool
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
class Namespace(object):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Value(object):
|
|
||||||
def __init__(self, typecode, value, lock=True):
|
|
||||||
self._typecode = typecode
|
|
||||||
self._value = value
|
|
||||||
def get(self):
|
|
||||||
return self._value
|
|
||||||
def set(self, value):
|
|
||||||
self._value = value
|
|
||||||
def __repr__(self):
|
|
||||||
return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value)
|
|
||||||
value = property(get, set)
|
|
||||||
|
|
||||||
def Array(typecode, sequence, lock=True):
|
|
||||||
return array.array(typecode, sequence)
|
|
||||||
|
|
||||||
class SyncManager(object):
|
|
||||||
Queue = JoinableQueue = six.moves.queue.Queue
|
|
||||||
Event = threading.Event
|
|
||||||
RLock = threading.RLock
|
|
||||||
BoundedSemaphore = threading.BoundedSemaphore
|
|
||||||
Condition = threading.Condition
|
|
||||||
Barrier = threading.Barrier
|
|
||||||
Pool = pool.Pool
|
|
||||||
list = list
|
|
||||||
dict = dict
|
|
||||||
Value = Value
|
|
||||||
Array = Array
|
|
||||||
Namespace = Namespace
|
|
||||||
__enter__ = lambda self: self
|
|
||||||
__exit__ = lambda *args: args
|
|
||||||
|
|
||||||
def start(self, initializer=None, initargs=None):
|
|
||||||
pass
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "multiprocessing.managers", _multiprocessing_managers_transform
|
|
||||||
)
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "multiprocessing", _multiprocessing_transform
|
|
||||||
)
|
|
||||||
|
|
@ -1,455 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2012-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
|
||||||
# Copyright (c) 2013-2014 Google, Inc.
|
|
||||||
# Copyright (c) 2014-2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2014 Eevee (Alex Munroe) <amunroe@yelp.com>
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru>
|
|
||||||
# Copyright (c) 2015 David Shea <dshea@redhat.com>
|
|
||||||
# Copyright (c) 2015 Philip Lorenz <philip@bithub.de>
|
|
||||||
# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net>
|
|
||||||
# Copyright (c) 2016 Mateusz Bysiek <mb@mbdev.pl>
|
|
||||||
# Copyright (c) 2017 Hugo <hugovk@users.noreply.github.com>
|
|
||||||
# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
|
|
||||||
# Copyright (c) 2018 Ville Skyttä <ville.skytta@iki.fi>
|
|
||||||
# Copyright (c) 2019 Ashley Whetter <ashley@awhetter.co.uk>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for the Python standard library."""
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import keyword
|
|
||||||
from textwrap import dedent
|
|
||||||
|
|
||||||
from astroid import MANAGER, UseInferenceDefault, inference_tip, InferenceError
|
|
||||||
from astroid import arguments
|
|
||||||
from astroid import exceptions
|
|
||||||
from astroid import nodes
|
|
||||||
from astroid.builder import AstroidBuilder, extract_node
|
|
||||||
from astroid import util
|
|
||||||
|
|
||||||
|
|
||||||
TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"}
|
|
||||||
ENUM_BASE_NAMES = {
|
|
||||||
"Enum",
|
|
||||||
"IntEnum",
|
|
||||||
"enum.Enum",
|
|
||||||
"enum.IntEnum",
|
|
||||||
"IntFlag",
|
|
||||||
"enum.IntFlag",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _infer_first(node, context):
|
|
||||||
if node is util.Uninferable:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
try:
|
|
||||||
value = next(node.infer(context=context))
|
|
||||||
if value is util.Uninferable:
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
else:
|
|
||||||
return value
|
|
||||||
except StopIteration:
|
|
||||||
raise InferenceError()
|
|
||||||
|
|
||||||
|
|
||||||
def _find_func_form_arguments(node, context):
|
|
||||||
def _extract_namedtuple_arg_or_keyword(position, key_name=None):
|
|
||||||
|
|
||||||
if len(args) > position:
|
|
||||||
return _infer_first(args[position], context)
|
|
||||||
if key_name and key_name in found_keywords:
|
|
||||||
return _infer_first(found_keywords[key_name], context)
|
|
||||||
|
|
||||||
args = node.args
|
|
||||||
keywords = node.keywords
|
|
||||||
found_keywords = (
|
|
||||||
{keyword.arg: keyword.value for keyword in keywords} if keywords else {}
|
|
||||||
)
|
|
||||||
|
|
||||||
name = _extract_namedtuple_arg_or_keyword(position=0, key_name="typename")
|
|
||||||
names = _extract_namedtuple_arg_or_keyword(position=1, key_name="field_names")
|
|
||||||
if name and names:
|
|
||||||
return name.value, names
|
|
||||||
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
|
|
||||||
|
|
||||||
def infer_func_form(node, base_type, context=None, enum=False):
|
|
||||||
"""Specific inference function for namedtuple or Python 3 enum. """
|
|
||||||
# node is a Call node, class name as first argument and generated class
|
|
||||||
# attributes as second argument
|
|
||||||
|
|
||||||
# namedtuple or enums list of attributes can be a list of strings or a
|
|
||||||
# whitespace-separate string
|
|
||||||
try:
|
|
||||||
name, names = _find_func_form_arguments(node, context)
|
|
||||||
try:
|
|
||||||
attributes = names.value.replace(",", " ").split()
|
|
||||||
except AttributeError:
|
|
||||||
if not enum:
|
|
||||||
attributes = [
|
|
||||||
_infer_first(const, context).value for const in names.elts
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
# Enums supports either iterator of (name, value) pairs
|
|
||||||
# or mappings.
|
|
||||||
if hasattr(names, "items") and isinstance(names.items, list):
|
|
||||||
attributes = [
|
|
||||||
_infer_first(const[0], context).value
|
|
||||||
for const in names.items
|
|
||||||
if isinstance(const[0], nodes.Const)
|
|
||||||
]
|
|
||||||
elif hasattr(names, "elts"):
|
|
||||||
# Enums can support either ["a", "b", "c"]
|
|
||||||
# or [("a", 1), ("b", 2), ...], but they can't
|
|
||||||
# be mixed.
|
|
||||||
if all(isinstance(const, nodes.Tuple) for const in names.elts):
|
|
||||||
attributes = [
|
|
||||||
_infer_first(const.elts[0], context).value
|
|
||||||
for const in names.elts
|
|
||||||
if isinstance(const, nodes.Tuple)
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
attributes = [
|
|
||||||
_infer_first(const, context).value for const in names.elts
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
raise AttributeError
|
|
||||||
if not attributes:
|
|
||||||
raise AttributeError
|
|
||||||
except (AttributeError, exceptions.InferenceError):
|
|
||||||
raise UseInferenceDefault()
|
|
||||||
|
|
||||||
attributes = [attr for attr in attributes if " " not in attr]
|
|
||||||
|
|
||||||
# If we can't infer the name of the class, don't crash, up to this point
|
|
||||||
# we know it is a namedtuple anyway.
|
|
||||||
name = name or "Uninferable"
|
|
||||||
# we want to return a Class node instance with proper attributes set
|
|
||||||
class_node = nodes.ClassDef(name, "docstring")
|
|
||||||
class_node.parent = node.parent
|
|
||||||
# set base class=tuple
|
|
||||||
class_node.bases.append(base_type)
|
|
||||||
# XXX add __init__(*attributes) method
|
|
||||||
for attr in attributes:
|
|
||||||
fake_node = nodes.EmptyNode()
|
|
||||||
fake_node.parent = class_node
|
|
||||||
fake_node.attrname = attr
|
|
||||||
class_node.instance_attrs[attr] = [fake_node]
|
|
||||||
return class_node, name, attributes
|
|
||||||
|
|
||||||
|
|
||||||
def _has_namedtuple_base(node):
|
|
||||||
"""Predicate for class inference tip
|
|
||||||
|
|
||||||
:type node: ClassDef
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return set(node.basenames) & TYPING_NAMEDTUPLE_BASENAMES
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like(node, name):
|
|
||||||
func = node.func
|
|
||||||
if isinstance(func, nodes.Attribute):
|
|
||||||
return func.attrname == name
|
|
||||||
if isinstance(func, nodes.Name):
|
|
||||||
return func.name == name
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
_looks_like_namedtuple = functools.partial(_looks_like, name="namedtuple")
|
|
||||||
_looks_like_enum = functools.partial(_looks_like, name="Enum")
|
|
||||||
_looks_like_typing_namedtuple = functools.partial(_looks_like, name="NamedTuple")
|
|
||||||
|
|
||||||
|
|
||||||
def infer_named_tuple(node, context=None):
|
|
||||||
"""Specific inference function for namedtuple Call node"""
|
|
||||||
tuple_base_name = nodes.Name(name="tuple", parent=node.root())
|
|
||||||
class_node, name, attributes = infer_func_form(
|
|
||||||
node, tuple_base_name, context=context
|
|
||||||
)
|
|
||||||
call_site = arguments.CallSite.from_call(node, context=context)
|
|
||||||
func = next(extract_node("import collections; collections.namedtuple").infer())
|
|
||||||
try:
|
|
||||||
rename = next(call_site.infer_argument(func, "rename", context)).bool_value()
|
|
||||||
except InferenceError:
|
|
||||||
rename = False
|
|
||||||
|
|
||||||
if rename:
|
|
||||||
attributes = _get_renamed_namedtuple_attributes(attributes)
|
|
||||||
|
|
||||||
replace_args = ", ".join("{arg}=None".format(arg=arg) for arg in attributes)
|
|
||||||
field_def = (
|
|
||||||
" {name} = property(lambda self: self[{index:d}], "
|
|
||||||
"doc='Alias for field number {index:d}')"
|
|
||||||
)
|
|
||||||
field_defs = "\n".join(
|
|
||||||
field_def.format(name=name, index=index)
|
|
||||||
for index, name in enumerate(attributes)
|
|
||||||
)
|
|
||||||
fake = AstroidBuilder(MANAGER).string_build(
|
|
||||||
"""
|
|
||||||
class %(name)s(tuple):
|
|
||||||
__slots__ = ()
|
|
||||||
_fields = %(fields)r
|
|
||||||
def _asdict(self):
|
|
||||||
return self.__dict__
|
|
||||||
@classmethod
|
|
||||||
def _make(cls, iterable, new=tuple.__new__, len=len):
|
|
||||||
return new(cls, iterable)
|
|
||||||
def _replace(self, %(replace_args)s):
|
|
||||||
return self
|
|
||||||
def __getnewargs__(self):
|
|
||||||
return tuple(self)
|
|
||||||
%(field_defs)s
|
|
||||||
"""
|
|
||||||
% {
|
|
||||||
"name": name,
|
|
||||||
"fields": attributes,
|
|
||||||
"field_defs": field_defs,
|
|
||||||
"replace_args": replace_args,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
class_node.locals["_asdict"] = fake.body[0].locals["_asdict"]
|
|
||||||
class_node.locals["_make"] = fake.body[0].locals["_make"]
|
|
||||||
class_node.locals["_replace"] = fake.body[0].locals["_replace"]
|
|
||||||
class_node.locals["_fields"] = fake.body[0].locals["_fields"]
|
|
||||||
for attr in attributes:
|
|
||||||
class_node.locals[attr] = fake.body[0].locals[attr]
|
|
||||||
# we use UseInferenceDefault, we can't be a generator so return an iterator
|
|
||||||
return iter([class_node])
|
|
||||||
|
|
||||||
|
|
||||||
def _get_renamed_namedtuple_attributes(field_names):
|
|
||||||
names = list(field_names)
|
|
||||||
seen = set()
|
|
||||||
for i, name in enumerate(field_names):
|
|
||||||
if (
|
|
||||||
not all(c.isalnum() or c == "_" for c in name)
|
|
||||||
or keyword.iskeyword(name)
|
|
||||||
or not name
|
|
||||||
or name[0].isdigit()
|
|
||||||
or name.startswith("_")
|
|
||||||
or name in seen
|
|
||||||
):
|
|
||||||
names[i] = "_%d" % i
|
|
||||||
seen.add(name)
|
|
||||||
return tuple(names)
|
|
||||||
|
|
||||||
|
|
||||||
def infer_enum(node, context=None):
|
|
||||||
""" Specific inference function for enum Call node. """
|
|
||||||
enum_meta = extract_node(
|
|
||||||
"""
|
|
||||||
class EnumMeta(object):
|
|
||||||
'docstring'
|
|
||||||
def __call__(self, node):
|
|
||||||
class EnumAttribute(object):
|
|
||||||
name = ''
|
|
||||||
value = 0
|
|
||||||
return EnumAttribute()
|
|
||||||
def __iter__(self):
|
|
||||||
class EnumAttribute(object):
|
|
||||||
name = ''
|
|
||||||
value = 0
|
|
||||||
return [EnumAttribute()]
|
|
||||||
def __reversed__(self):
|
|
||||||
class EnumAttribute(object):
|
|
||||||
name = ''
|
|
||||||
value = 0
|
|
||||||
return (EnumAttribute, )
|
|
||||||
def __next__(self):
|
|
||||||
return next(iter(self))
|
|
||||||
def __getitem__(self, attr):
|
|
||||||
class Value(object):
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
return ''
|
|
||||||
@property
|
|
||||||
def value(self):
|
|
||||||
return attr
|
|
||||||
|
|
||||||
return Value()
|
|
||||||
__members__ = ['']
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
class_node = infer_func_form(node, enum_meta, context=context, enum=True)[0]
|
|
||||||
return iter([class_node.instantiate_class()])
|
|
||||||
|
|
||||||
|
|
||||||
INT_FLAG_ADDITION_METHODS = """
|
|
||||||
def __or__(self, other):
|
|
||||||
return {name}(self.value | other.value)
|
|
||||||
def __and__(self, other):
|
|
||||||
return {name}(self.value & other.value)
|
|
||||||
def __xor__(self, other):
|
|
||||||
return {name}(self.value ^ other.value)
|
|
||||||
def __add__(self, other):
|
|
||||||
return {name}(self.value + other.value)
|
|
||||||
def __div__(self, other):
|
|
||||||
return {name}(self.value / other.value)
|
|
||||||
def __invert__(self):
|
|
||||||
return {name}(~self.value)
|
|
||||||
def __mul__(self, other):
|
|
||||||
return {name}(self.value * other.value)
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def infer_enum_class(node):
|
|
||||||
""" Specific inference for enums. """
|
|
||||||
for basename in node.basenames:
|
|
||||||
# TODO: doesn't handle subclasses yet. This implementation
|
|
||||||
# is a hack to support enums.
|
|
||||||
if basename not in ENUM_BASE_NAMES:
|
|
||||||
continue
|
|
||||||
if node.root().name == "enum":
|
|
||||||
# Skip if the class is directly from enum module.
|
|
||||||
break
|
|
||||||
for local, values in node.locals.items():
|
|
||||||
if any(not isinstance(value, nodes.AssignName) for value in values):
|
|
||||||
continue
|
|
||||||
|
|
||||||
targets = []
|
|
||||||
stmt = values[0].statement()
|
|
||||||
if isinstance(stmt, nodes.Assign):
|
|
||||||
if isinstance(stmt.targets[0], nodes.Tuple):
|
|
||||||
targets = stmt.targets[0].itered()
|
|
||||||
else:
|
|
||||||
targets = stmt.targets
|
|
||||||
elif isinstance(stmt, nodes.AnnAssign):
|
|
||||||
targets = [stmt.target]
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
inferred_return_value = None
|
|
||||||
if isinstance(stmt, nodes.Assign):
|
|
||||||
if isinstance(stmt.value, nodes.Const):
|
|
||||||
if isinstance(stmt.value.value, str):
|
|
||||||
inferred_return_value = repr(stmt.value.value)
|
|
||||||
else:
|
|
||||||
inferred_return_value = stmt.value.value
|
|
||||||
else:
|
|
||||||
inferred_return_value = stmt.value.as_string()
|
|
||||||
|
|
||||||
new_targets = []
|
|
||||||
for target in targets:
|
|
||||||
# Replace all the assignments with our mocked class.
|
|
||||||
classdef = dedent(
|
|
||||||
"""
|
|
||||||
class {name}({types}):
|
|
||||||
@property
|
|
||||||
def value(self):
|
|
||||||
return {return_value}
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
return "{name}"
|
|
||||||
""".format(
|
|
||||||
name=target.name,
|
|
||||||
types=", ".join(node.basenames),
|
|
||||||
return_value=inferred_return_value,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if "IntFlag" in basename:
|
|
||||||
# Alright, we need to add some additional methods.
|
|
||||||
# Unfortunately we still can't infer the resulting objects as
|
|
||||||
# Enum members, but once we'll be able to do that, the following
|
|
||||||
# should result in some nice symbolic execution
|
|
||||||
classdef += INT_FLAG_ADDITION_METHODS.format(name=target.name)
|
|
||||||
|
|
||||||
fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name]
|
|
||||||
fake.parent = target.parent
|
|
||||||
for method in node.mymethods():
|
|
||||||
fake.locals[method.name] = [method]
|
|
||||||
new_targets.append(fake.instantiate_class())
|
|
||||||
node.locals[local] = new_targets
|
|
||||||
break
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
def infer_typing_namedtuple_class(class_node, context=None):
|
|
||||||
"""Infer a subclass of typing.NamedTuple"""
|
|
||||||
# Check if it has the corresponding bases
|
|
||||||
annassigns_fields = [
|
|
||||||
annassign.target.name
|
|
||||||
for annassign in class_node.body
|
|
||||||
if isinstance(annassign, nodes.AnnAssign)
|
|
||||||
]
|
|
||||||
code = dedent(
|
|
||||||
"""
|
|
||||||
from collections import namedtuple
|
|
||||||
namedtuple({typename!r}, {fields!r})
|
|
||||||
"""
|
|
||||||
).format(typename=class_node.name, fields=",".join(annassigns_fields))
|
|
||||||
node = extract_node(code)
|
|
||||||
generated_class_node = next(infer_named_tuple(node, context))
|
|
||||||
for method in class_node.mymethods():
|
|
||||||
generated_class_node.locals[method.name] = [method]
|
|
||||||
|
|
||||||
for assign in class_node.body:
|
|
||||||
if not isinstance(assign, nodes.Assign):
|
|
||||||
continue
|
|
||||||
|
|
||||||
for target in assign.targets:
|
|
||||||
attr = target.name
|
|
||||||
generated_class_node.locals[attr] = class_node.locals[attr]
|
|
||||||
|
|
||||||
return iter((generated_class_node,))
|
|
||||||
|
|
||||||
|
|
||||||
def infer_typing_namedtuple(node, context=None):
|
|
||||||
"""Infer a typing.NamedTuple(...) call."""
|
|
||||||
# This is essentially a namedtuple with different arguments
|
|
||||||
# so we extract the args and infer a named tuple.
|
|
||||||
try:
|
|
||||||
func = next(node.func.infer())
|
|
||||||
except InferenceError:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if func.qname() != "typing.NamedTuple":
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if len(node.args) != 2:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
if not isinstance(node.args[1], (nodes.List, nodes.Tuple)):
|
|
||||||
raise UseInferenceDefault
|
|
||||||
|
|
||||||
names = []
|
|
||||||
for elt in node.args[1].elts:
|
|
||||||
if not isinstance(elt, (nodes.List, nodes.Tuple)):
|
|
||||||
raise UseInferenceDefault
|
|
||||||
if len(elt.elts) != 2:
|
|
||||||
raise UseInferenceDefault
|
|
||||||
names.append(elt.elts[0].as_string())
|
|
||||||
|
|
||||||
typename = node.args[0].as_string()
|
|
||||||
if names:
|
|
||||||
field_names = "({},)".format(",".join(names))
|
|
||||||
else:
|
|
||||||
field_names = "''"
|
|
||||||
node = extract_node(
|
|
||||||
"namedtuple({typename}, {fields})".format(typename=typename, fields=field_names)
|
|
||||||
)
|
|
||||||
return infer_named_tuple(node, context)
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.Call, inference_tip(infer_named_tuple), _looks_like_namedtuple
|
|
||||||
)
|
|
||||||
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum), _looks_like_enum)
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.ClassDef,
|
|
||||||
infer_enum_class,
|
|
||||||
predicate=lambda cls: any(
|
|
||||||
basename for basename in cls.basenames if basename in ENUM_BASE_NAMES
|
|
||||||
),
|
|
||||||
)
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.ClassDef, inference_tip(infer_typing_namedtuple_class), _has_namedtuple_base
|
|
||||||
)
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple
|
|
||||||
)
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
# Copyright (c) 2015-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Hooks for nose library."""
|
|
||||||
|
|
||||||
import re
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
import astroid.builder
|
|
||||||
|
|
||||||
_BUILDER = astroid.builder.AstroidBuilder(astroid.MANAGER)
|
|
||||||
|
|
||||||
|
|
||||||
def _pep8(name, caps=re.compile("([A-Z])")):
|
|
||||||
return caps.sub(lambda m: "_" + m.groups()[0].lower(), name)
|
|
||||||
|
|
||||||
|
|
||||||
def _nose_tools_functions():
|
|
||||||
"""Get an iterator of names and bound methods."""
|
|
||||||
module = _BUILDER.string_build(
|
|
||||||
textwrap.dedent(
|
|
||||||
"""
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
class Test(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
a = Test()
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
case = next(module["a"].infer())
|
|
||||||
except astroid.InferenceError:
|
|
||||||
return
|
|
||||||
for method in case.methods():
|
|
||||||
if method.name.startswith("assert") and "_" not in method.name:
|
|
||||||
pep8_name = _pep8(method.name)
|
|
||||||
yield pep8_name, astroid.BoundMethod(method, case)
|
|
||||||
if method.name == "assertEqual":
|
|
||||||
# nose also exports assert_equals.
|
|
||||||
yield "assert_equals", astroid.BoundMethod(method, case)
|
|
||||||
|
|
||||||
|
|
||||||
def _nose_tools_transform(node):
|
|
||||||
for method_name, method in _nose_tools_functions():
|
|
||||||
node.locals[method_name] = [method]
|
|
||||||
|
|
||||||
|
|
||||||
def _nose_tools_trivial_transform():
|
|
||||||
"""Custom transform for the nose.tools module."""
|
|
||||||
stub = _BUILDER.string_build("""__all__ = []""")
|
|
||||||
all_entries = ["ok_", "eq_"]
|
|
||||||
|
|
||||||
for pep8_name, method in _nose_tools_functions():
|
|
||||||
all_entries.append(pep8_name)
|
|
||||||
stub[pep8_name] = method
|
|
||||||
|
|
||||||
# Update the __all__ variable, since nose.tools
|
|
||||||
# does this manually with .append.
|
|
||||||
all_assign = stub["__all__"].parent
|
|
||||||
all_object = astroid.List(all_entries)
|
|
||||||
all_object.parent = all_assign
|
|
||||||
all_assign.value = all_object
|
|
||||||
return stub
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "nose.tools.trivial", _nose_tools_trivial_transform
|
|
||||||
)
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.Module, _nose_tools_transform, lambda n: n.name == "nose.tools"
|
|
||||||
)
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Copyright (c) 2019 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for numpy.core.fromnumeric module."""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def numpy_core_fromnumeric_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
def sum(a, axis=None, dtype=None, out=None, keepdims=None, initial=None):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "numpy.core.fromnumeric", numpy_core_fromnumeric_transform
|
|
||||||
)
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
# Copyright (c) 2019 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for numpy.core.function_base module."""
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import astroid
|
|
||||||
from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member
|
|
||||||
|
|
||||||
|
|
||||||
METHODS_TO_BE_INFERRED = {
|
|
||||||
"linspace": """def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"logspace": """def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"geomspace": """def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
}
|
|
||||||
|
|
||||||
for func_name, func_src in METHODS_TO_BE_INFERRED.items():
|
|
||||||
inference_function = functools.partial(infer_numpy_member, func_src)
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.Attribute,
|
|
||||||
astroid.inference_tip(inference_function),
|
|
||||||
functools.partial(looks_like_numpy_member, func_name),
|
|
||||||
)
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
# Copyright (c) 2019-2020 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for numpy.core.multiarray module."""
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import astroid
|
|
||||||
from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member
|
|
||||||
|
|
||||||
|
|
||||||
def numpy_core_multiarray_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
# different functions defined in multiarray.py
|
|
||||||
def inner(a, b):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
def vdot(a, b):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "numpy.core.multiarray", numpy_core_multiarray_transform
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
METHODS_TO_BE_INFERRED = {
|
|
||||||
"array": """def array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"dot": """def dot(a, b, out=None):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"empty_like": """def empty_like(a, dtype=None, order='K', subok=True):
|
|
||||||
return numpy.ndarray((0, 0))""",
|
|
||||||
"concatenate": """def concatenate(arrays, axis=None, out=None):
|
|
||||||
return numpy.ndarray((0, 0))""",
|
|
||||||
"where": """def where(condition, x=None, y=None):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"empty": """def empty(shape, dtype=float, order='C'):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"bincount": """def bincount(x, weights=None, minlength=0):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"busday_count": """def busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"busday_offset": """def busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"can_cast": """def can_cast(from_, to, casting='safe'):
|
|
||||||
return True""",
|
|
||||||
"copyto": """def copyto(dst, src, casting='same_kind', where=True):
|
|
||||||
return None""",
|
|
||||||
"datetime_as_string": """def datetime_as_string(arr, unit=None, timezone='naive', casting='same_kind'):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"is_busday": """def is_busday(dates, weekmask='1111100', holidays=None, busdaycal=None, out=None):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"lexsort": """def lexsort(keys, axis=-1):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"may_share_memory": """def may_share_memory(a, b, max_work=None):
|
|
||||||
return True""",
|
|
||||||
# Not yet available because dtype is not yet present in those brains
|
|
||||||
# "min_scalar_type": """def min_scalar_type(a):
|
|
||||||
# return numpy.dtype('int16')""",
|
|
||||||
"packbits": """def packbits(a, axis=None, bitorder='big'):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
# Not yet available because dtype is not yet present in those brains
|
|
||||||
# "result_type": """def result_type(*arrays_and_dtypes):
|
|
||||||
# return numpy.dtype('int16')""",
|
|
||||||
"shares_memory": """def shares_memory(a, b, max_work=None):
|
|
||||||
return True""",
|
|
||||||
"unpackbits": """def unpackbits(a, axis=None, count=None, bitorder='big'):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
"unravel_index": """def unravel_index(indices, shape, order='C'):
|
|
||||||
return (numpy.ndarray([0, 0]),)""",
|
|
||||||
"zeros": """def zeros(shape, dtype=float, order='C'):
|
|
||||||
return numpy.ndarray([0, 0])""",
|
|
||||||
}
|
|
||||||
|
|
||||||
for method_name, function_src in METHODS_TO_BE_INFERRED.items():
|
|
||||||
inference_function = functools.partial(infer_numpy_member, function_src)
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.Attribute,
|
|
||||||
astroid.inference_tip(inference_function),
|
|
||||||
functools.partial(looks_like_numpy_member, method_name),
|
|
||||||
)
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.Name,
|
|
||||||
astroid.inference_tip(inference_function),
|
|
||||||
functools.partial(looks_like_numpy_member, method_name),
|
|
||||||
)
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
# Copyright (c) 2019 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for numpy.core.numeric module."""
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import astroid
|
|
||||||
from brain_numpy_utils import looks_like_numpy_member, infer_numpy_member
|
|
||||||
|
|
||||||
|
|
||||||
def numpy_core_numeric_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
# different functions defined in numeric.py
|
|
||||||
import numpy
|
|
||||||
def zeros_like(a, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0))
|
|
||||||
def ones_like(a, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0))
|
|
||||||
def full_like(a, fill_value, dtype=None, order='K', subok=True): return numpy.ndarray((0, 0))
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "numpy.core.numeric", numpy_core_numeric_transform
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
METHODS_TO_BE_INFERRED = {
|
|
||||||
"ones": """def ones(shape, dtype=None, order='C'):
|
|
||||||
return numpy.ndarray([0, 0])"""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for method_name, function_src in METHODS_TO_BE_INFERRED.items():
|
|
||||||
inference_function = functools.partial(infer_numpy_member, function_src)
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.Attribute,
|
|
||||||
astroid.inference_tip(inference_function),
|
|
||||||
functools.partial(looks_like_numpy_member, method_name),
|
|
||||||
)
|
|
||||||
|
|
@ -1,254 +0,0 @@
|
||||||
# Copyright (c) 2019-2020 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
# TODO(hippo91) : correct the methods signature.
|
|
||||||
|
|
||||||
"""Astroid hooks for numpy.core.numerictypes module."""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def numpy_core_numerictypes_transform():
|
|
||||||
# TODO: Uniformize the generic API with the ndarray one.
|
|
||||||
# According to numpy doc the generic object should expose
|
|
||||||
# the same API than ndarray. This has been done here partially
|
|
||||||
# through the astype method.
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
# different types defined in numerictypes.py
|
|
||||||
class generic(object):
|
|
||||||
def __init__(self, value):
|
|
||||||
self.T = None
|
|
||||||
self.base = None
|
|
||||||
self.data = None
|
|
||||||
self.dtype = None
|
|
||||||
self.flags = None
|
|
||||||
self.flat = None
|
|
||||||
self.imag = None
|
|
||||||
self.itemsize = None
|
|
||||||
self.nbytes = None
|
|
||||||
self.ndim = None
|
|
||||||
self.real = None
|
|
||||||
self.size = None
|
|
||||||
self.strides = None
|
|
||||||
|
|
||||||
def all(self): return uninferable
|
|
||||||
def any(self): return uninferable
|
|
||||||
def argmax(self): return uninferable
|
|
||||||
def argmin(self): return uninferable
|
|
||||||
def argsort(self): return uninferable
|
|
||||||
def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): return np.ndarray([0, 0])
|
|
||||||
def base(self): return uninferable
|
|
||||||
def byteswap(self): return uninferable
|
|
||||||
def choose(self): return uninferable
|
|
||||||
def clip(self): return uninferable
|
|
||||||
def compress(self): return uninferable
|
|
||||||
def conj(self): return uninferable
|
|
||||||
def conjugate(self): return uninferable
|
|
||||||
def copy(self): return uninferable
|
|
||||||
def cumprod(self): return uninferable
|
|
||||||
def cumsum(self): return uninferable
|
|
||||||
def data(self): return uninferable
|
|
||||||
def diagonal(self): return uninferable
|
|
||||||
def dtype(self): return uninferable
|
|
||||||
def dump(self): return uninferable
|
|
||||||
def dumps(self): return uninferable
|
|
||||||
def fill(self): return uninferable
|
|
||||||
def flags(self): return uninferable
|
|
||||||
def flat(self): return uninferable
|
|
||||||
def flatten(self): return uninferable
|
|
||||||
def getfield(self): return uninferable
|
|
||||||
def imag(self): return uninferable
|
|
||||||
def item(self): return uninferable
|
|
||||||
def itemset(self): return uninferable
|
|
||||||
def itemsize(self): return uninferable
|
|
||||||
def max(self): return uninferable
|
|
||||||
def mean(self): return uninferable
|
|
||||||
def min(self): return uninferable
|
|
||||||
def nbytes(self): return uninferable
|
|
||||||
def ndim(self): return uninferable
|
|
||||||
def newbyteorder(self): return uninferable
|
|
||||||
def nonzero(self): return uninferable
|
|
||||||
def prod(self): return uninferable
|
|
||||||
def ptp(self): return uninferable
|
|
||||||
def put(self): return uninferable
|
|
||||||
def ravel(self): return uninferable
|
|
||||||
def real(self): return uninferable
|
|
||||||
def repeat(self): return uninferable
|
|
||||||
def reshape(self): return uninferable
|
|
||||||
def resize(self): return uninferable
|
|
||||||
def round(self): return uninferable
|
|
||||||
def searchsorted(self): return uninferable
|
|
||||||
def setfield(self): return uninferable
|
|
||||||
def setflags(self): return uninferable
|
|
||||||
def shape(self): return uninferable
|
|
||||||
def size(self): return uninferable
|
|
||||||
def sort(self): return uninferable
|
|
||||||
def squeeze(self): return uninferable
|
|
||||||
def std(self): return uninferable
|
|
||||||
def strides(self): return uninferable
|
|
||||||
def sum(self): return uninferable
|
|
||||||
def swapaxes(self): return uninferable
|
|
||||||
def take(self): return uninferable
|
|
||||||
def tobytes(self): return uninferable
|
|
||||||
def tofile(self): return uninferable
|
|
||||||
def tolist(self): return uninferable
|
|
||||||
def tostring(self): return uninferable
|
|
||||||
def trace(self): return uninferable
|
|
||||||
def transpose(self): return uninferable
|
|
||||||
def var(self): return uninferable
|
|
||||||
def view(self): return uninferable
|
|
||||||
|
|
||||||
|
|
||||||
class dtype(object):
|
|
||||||
def __init__(self, obj, align=False, copy=False):
|
|
||||||
self.alignment = None
|
|
||||||
self.base = None
|
|
||||||
self.byteorder = None
|
|
||||||
self.char = None
|
|
||||||
self.descr = None
|
|
||||||
self.fields = None
|
|
||||||
self.flags = None
|
|
||||||
self.hasobject = None
|
|
||||||
self.isalignedstruct = None
|
|
||||||
self.isbuiltin = None
|
|
||||||
self.isnative = None
|
|
||||||
self.itemsize = None
|
|
||||||
self.kind = None
|
|
||||||
self.metadata = None
|
|
||||||
self.name = None
|
|
||||||
self.names = None
|
|
||||||
self.num = None
|
|
||||||
self.shape = None
|
|
||||||
self.str = None
|
|
||||||
self.subdtype = None
|
|
||||||
self.type = None
|
|
||||||
|
|
||||||
def newbyteorder(self, new_order='S'): return uninferable
|
|
||||||
def __neg__(self): return uninferable
|
|
||||||
|
|
||||||
class busdaycalendar(object):
|
|
||||||
def __init__(self, weekmask='1111100', holidays=None):
|
|
||||||
self.holidays = None
|
|
||||||
self.weekmask = None
|
|
||||||
|
|
||||||
class flexible(generic): pass
|
|
||||||
class bool_(generic): pass
|
|
||||||
class number(generic):
|
|
||||||
def __neg__(self): return uninferable
|
|
||||||
class datetime64(generic):
|
|
||||||
def __init__(self, nb, unit=None): pass
|
|
||||||
|
|
||||||
|
|
||||||
class void(flexible):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.base = None
|
|
||||||
self.dtype = None
|
|
||||||
self.flags = None
|
|
||||||
def getfield(self): return uninferable
|
|
||||||
def setfield(self): return uninferable
|
|
||||||
|
|
||||||
|
|
||||||
class character(flexible): pass
|
|
||||||
|
|
||||||
|
|
||||||
class integer(number):
|
|
||||||
def __init__(self, value):
|
|
||||||
self.denominator = None
|
|
||||||
self.numerator = None
|
|
||||||
|
|
||||||
|
|
||||||
class inexact(number): pass
|
|
||||||
|
|
||||||
|
|
||||||
class str_(str, character):
|
|
||||||
def maketrans(self, x, y=None, z=None): return uninferable
|
|
||||||
|
|
||||||
|
|
||||||
class bytes_(bytes, character):
|
|
||||||
def fromhex(self, string): return uninferable
|
|
||||||
def maketrans(self, frm, to): return uninferable
|
|
||||||
|
|
||||||
|
|
||||||
class signedinteger(integer): pass
|
|
||||||
|
|
||||||
|
|
||||||
class unsignedinteger(integer): pass
|
|
||||||
|
|
||||||
|
|
||||||
class complexfloating(inexact): pass
|
|
||||||
|
|
||||||
|
|
||||||
class floating(inexact): pass
|
|
||||||
|
|
||||||
|
|
||||||
class float64(floating, float):
|
|
||||||
def fromhex(self, string): return uninferable
|
|
||||||
|
|
||||||
|
|
||||||
class uint64(unsignedinteger): pass
|
|
||||||
class complex64(complexfloating): pass
|
|
||||||
class int16(signedinteger): pass
|
|
||||||
class float96(floating): pass
|
|
||||||
class int8(signedinteger): pass
|
|
||||||
class uint32(unsignedinteger): pass
|
|
||||||
class uint8(unsignedinteger): pass
|
|
||||||
class _typedict(dict): pass
|
|
||||||
class complex192(complexfloating): pass
|
|
||||||
class timedelta64(signedinteger):
|
|
||||||
def __init__(self, nb, unit=None): pass
|
|
||||||
class int32(signedinteger): pass
|
|
||||||
class uint16(unsignedinteger): pass
|
|
||||||
class float32(floating): pass
|
|
||||||
class complex128(complexfloating, complex): pass
|
|
||||||
class float16(floating): pass
|
|
||||||
class int64(signedinteger): pass
|
|
||||||
|
|
||||||
buffer_type = memoryview
|
|
||||||
bool8 = bool_
|
|
||||||
byte = int8
|
|
||||||
bytes0 = bytes_
|
|
||||||
cdouble = complex128
|
|
||||||
cfloat = complex128
|
|
||||||
clongdouble = complex192
|
|
||||||
clongfloat = complex192
|
|
||||||
complex_ = complex128
|
|
||||||
csingle = complex64
|
|
||||||
double = float64
|
|
||||||
float_ = float64
|
|
||||||
half = float16
|
|
||||||
int0 = int32
|
|
||||||
int_ = int32
|
|
||||||
intc = int32
|
|
||||||
intp = int32
|
|
||||||
long = int32
|
|
||||||
longcomplex = complex192
|
|
||||||
longdouble = float96
|
|
||||||
longfloat = float96
|
|
||||||
longlong = int64
|
|
||||||
object0 = object_
|
|
||||||
object_ = object_
|
|
||||||
short = int16
|
|
||||||
single = float32
|
|
||||||
singlecomplex = complex64
|
|
||||||
str0 = str_
|
|
||||||
string_ = bytes_
|
|
||||||
ubyte = uint8
|
|
||||||
uint = uint32
|
|
||||||
uint0 = uint32
|
|
||||||
uintc = uint32
|
|
||||||
uintp = uint32
|
|
||||||
ulonglong = uint64
|
|
||||||
unicode = str_
|
|
||||||
unicode_ = str_
|
|
||||||
ushort = uint16
|
|
||||||
void0 = void
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "numpy.core.numerictypes", numpy_core_numerictypes_transform
|
|
||||||
)
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
# Copyright (c) 2019 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for numpy.core.umath module."""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def numpy_core_umath_transform():
|
|
||||||
ufunc_optional_keyword_arguments = (
|
|
||||||
"""out=None, where=True, casting='same_kind', order='K', """
|
|
||||||
"""dtype=None, subok=True"""
|
|
||||||
)
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
class FakeUfunc:
|
|
||||||
def __init__(self):
|
|
||||||
self.__doc__ = str()
|
|
||||||
self.__name__ = str()
|
|
||||||
self.nin = 0
|
|
||||||
self.nout = 0
|
|
||||||
self.nargs = 0
|
|
||||||
self.ntypes = 0
|
|
||||||
self.types = None
|
|
||||||
self.identity = None
|
|
||||||
self.signature = None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def reduce(cls, a, axis=None, dtype=None, out=None):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def accumulate(cls, array, axis=None, dtype=None, out=None):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def reduceat(cls, a, indices, axis=None, dtype=None, out=None):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def outer(cls, A, B, **kwargs):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def at(cls, a, indices, b=None):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
class FakeUfuncOneArg(FakeUfunc):
|
|
||||||
def __call__(self, x, {opt_args:s}):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
class FakeUfuncOneArgBis(FakeUfunc):
|
|
||||||
def __call__(self, x, {opt_args:s}):
|
|
||||||
return numpy.ndarray([0, 0]), numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
class FakeUfuncTwoArgs(FakeUfunc):
|
|
||||||
def __call__(self, x1, x2, {opt_args:s}):
|
|
||||||
return numpy.ndarray([0, 0])
|
|
||||||
|
|
||||||
# Constants
|
|
||||||
e = 2.718281828459045
|
|
||||||
euler_gamma = 0.5772156649015329
|
|
||||||
|
|
||||||
# One arg functions with optional kwargs
|
|
||||||
arccos = FakeUfuncOneArg()
|
|
||||||
arccosh = FakeUfuncOneArg()
|
|
||||||
arcsin = FakeUfuncOneArg()
|
|
||||||
arcsinh = FakeUfuncOneArg()
|
|
||||||
arctan = FakeUfuncOneArg()
|
|
||||||
arctanh = FakeUfuncOneArg()
|
|
||||||
cbrt = FakeUfuncOneArg()
|
|
||||||
conj = FakeUfuncOneArg()
|
|
||||||
conjugate = FakeUfuncOneArg()
|
|
||||||
cosh = FakeUfuncOneArg()
|
|
||||||
deg2rad = FakeUfuncOneArg()
|
|
||||||
exp2 = FakeUfuncOneArg()
|
|
||||||
expm1 = FakeUfuncOneArg()
|
|
||||||
fabs = FakeUfuncOneArg()
|
|
||||||
frexp = FakeUfuncOneArgBis()
|
|
||||||
isfinite = FakeUfuncOneArg()
|
|
||||||
isinf = FakeUfuncOneArg()
|
|
||||||
log = FakeUfuncOneArg()
|
|
||||||
log1p = FakeUfuncOneArg()
|
|
||||||
log2 = FakeUfuncOneArg()
|
|
||||||
logical_not = FakeUfuncOneArg()
|
|
||||||
modf = FakeUfuncOneArgBis()
|
|
||||||
negative = FakeUfuncOneArg()
|
|
||||||
positive = FakeUfuncOneArg()
|
|
||||||
rad2deg = FakeUfuncOneArg()
|
|
||||||
reciprocal = FakeUfuncOneArg()
|
|
||||||
rint = FakeUfuncOneArg()
|
|
||||||
sign = FakeUfuncOneArg()
|
|
||||||
signbit = FakeUfuncOneArg()
|
|
||||||
sinh = FakeUfuncOneArg()
|
|
||||||
spacing = FakeUfuncOneArg()
|
|
||||||
square = FakeUfuncOneArg()
|
|
||||||
tan = FakeUfuncOneArg()
|
|
||||||
tanh = FakeUfuncOneArg()
|
|
||||||
trunc = FakeUfuncOneArg()
|
|
||||||
|
|
||||||
# Two args functions with optional kwargs
|
|
||||||
bitwise_and = FakeUfuncTwoArgs()
|
|
||||||
bitwise_or = FakeUfuncTwoArgs()
|
|
||||||
bitwise_xor = FakeUfuncTwoArgs()
|
|
||||||
copysign = FakeUfuncTwoArgs()
|
|
||||||
divide = FakeUfuncTwoArgs()
|
|
||||||
divmod = FakeUfuncTwoArgs()
|
|
||||||
equal = FakeUfuncTwoArgs()
|
|
||||||
float_power = FakeUfuncTwoArgs()
|
|
||||||
floor_divide = FakeUfuncTwoArgs()
|
|
||||||
fmax = FakeUfuncTwoArgs()
|
|
||||||
fmin = FakeUfuncTwoArgs()
|
|
||||||
fmod = FakeUfuncTwoArgs()
|
|
||||||
greater = FakeUfuncTwoArgs()
|
|
||||||
gcd = FakeUfuncTwoArgs()
|
|
||||||
hypot = FakeUfuncTwoArgs()
|
|
||||||
heaviside = FakeUfuncTwoArgs()
|
|
||||||
lcm = FakeUfuncTwoArgs()
|
|
||||||
ldexp = FakeUfuncTwoArgs()
|
|
||||||
left_shift = FakeUfuncTwoArgs()
|
|
||||||
less = FakeUfuncTwoArgs()
|
|
||||||
logaddexp = FakeUfuncTwoArgs()
|
|
||||||
logaddexp2 = FakeUfuncTwoArgs()
|
|
||||||
logical_and = FakeUfuncTwoArgs()
|
|
||||||
logical_or = FakeUfuncTwoArgs()
|
|
||||||
logical_xor = FakeUfuncTwoArgs()
|
|
||||||
maximum = FakeUfuncTwoArgs()
|
|
||||||
minimum = FakeUfuncTwoArgs()
|
|
||||||
nextafter = FakeUfuncTwoArgs()
|
|
||||||
not_equal = FakeUfuncTwoArgs()
|
|
||||||
power = FakeUfuncTwoArgs()
|
|
||||||
remainder = FakeUfuncTwoArgs()
|
|
||||||
right_shift = FakeUfuncTwoArgs()
|
|
||||||
subtract = FakeUfuncTwoArgs()
|
|
||||||
true_divide = FakeUfuncTwoArgs()
|
|
||||||
""".format(
|
|
||||||
opt_args=ufunc_optional_keyword_arguments
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "numpy.core.umath", numpy_core_umath_transform
|
|
||||||
)
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
# Copyright (c) 2015-2016, 2018-2019 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2017-2020 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for numpy ndarray class."""
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def infer_numpy_ndarray(node, context=None):
|
|
||||||
ndarray = """
|
|
||||||
class ndarray(object):
|
|
||||||
def __init__(self, shape, dtype=float, buffer=None, offset=0,
|
|
||||||
strides=None, order=None):
|
|
||||||
self.T = None
|
|
||||||
self.base = None
|
|
||||||
self.ctypes = None
|
|
||||||
self.data = None
|
|
||||||
self.dtype = None
|
|
||||||
self.flags = None
|
|
||||||
self.flat = None
|
|
||||||
self.imag = np.ndarray([0, 0])
|
|
||||||
self.itemsize = None
|
|
||||||
self.nbytes = None
|
|
||||||
self.ndim = None
|
|
||||||
self.real = np.ndarray([0, 0])
|
|
||||||
self.shape = numpy.ndarray([0, 0])
|
|
||||||
self.size = None
|
|
||||||
self.strides = None
|
|
||||||
|
|
||||||
def __abs__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __add__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __and__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __array__(self, dtype=None): return numpy.ndarray([0, 0])
|
|
||||||
def __array_wrap__(self, obj): return numpy.ndarray([0, 0])
|
|
||||||
def __contains__(self, key): return True
|
|
||||||
def __copy__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __deepcopy__(self, memo): return numpy.ndarray([0, 0])
|
|
||||||
def __divmod__(self, value): return (numpy.ndarray([0, 0]), numpy.ndarray([0, 0]))
|
|
||||||
def __eq__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __float__(self): return 0.
|
|
||||||
def __floordiv__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __ge__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __getitem__(self, key): return uninferable
|
|
||||||
def __gt__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __iadd__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __iand__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __ifloordiv__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __ilshift__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __imod__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __imul__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __int__(self): return 0
|
|
||||||
def __invert__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __ior__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __ipow__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __irshift__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __isub__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __itruediv__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __ixor__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __le__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __len__(self): return 1
|
|
||||||
def __lshift__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __lt__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __matmul__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __mod__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __mul__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __ne__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __neg__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __or__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __pos__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __pow__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __repr__(self): return str()
|
|
||||||
def __rshift__(self): return numpy.ndarray([0, 0])
|
|
||||||
def __setitem__(self, key, value): return uninferable
|
|
||||||
def __str__(self): return str()
|
|
||||||
def __sub__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __truediv__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def __xor__(self, value): return numpy.ndarray([0, 0])
|
|
||||||
def all(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def any(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def argmax(self, axis=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def argmin(self, axis=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def argpartition(self, kth, axis=-1, kind='introselect', order=None): return np.ndarray([0, 0])
|
|
||||||
def argsort(self, axis=-1, kind='quicksort', order=None): return np.ndarray([0, 0])
|
|
||||||
def astype(self, dtype, order='K', casting='unsafe', subok=True, copy=True): return np.ndarray([0, 0])
|
|
||||||
def byteswap(self, inplace=False): return np.ndarray([0, 0])
|
|
||||||
def choose(self, choices, out=None, mode='raise'): return np.ndarray([0, 0])
|
|
||||||
def clip(self, min=None, max=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def compress(self, condition, axis=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def conj(self): return np.ndarray([0, 0])
|
|
||||||
def conjugate(self): return np.ndarray([0, 0])
|
|
||||||
def copy(self, order='C'): return np.ndarray([0, 0])
|
|
||||||
def cumprod(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def cumsum(self, axis=None, dtype=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def diagonal(self, offset=0, axis1=0, axis2=1): return np.ndarray([0, 0])
|
|
||||||
def dot(self, b, out=None): return np.ndarray([0, 0])
|
|
||||||
def dump(self, file): return None
|
|
||||||
def dumps(self): return str()
|
|
||||||
def fill(self, value): return None
|
|
||||||
def flatten(self, order='C'): return np.ndarray([0, 0])
|
|
||||||
def getfield(self, dtype, offset=0): return np.ndarray([0, 0])
|
|
||||||
def item(self, *args): return uninferable
|
|
||||||
def itemset(self, *args): return None
|
|
||||||
def max(self, axis=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def mean(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def min(self, axis=None, out=None, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def newbyteorder(self, new_order='S'): return np.ndarray([0, 0])
|
|
||||||
def nonzero(self): return (1,)
|
|
||||||
def partition(self, kth, axis=-1, kind='introselect', order=None): return None
|
|
||||||
def prod(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def ptp(self, axis=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def put(self, indices, values, mode='raise'): return None
|
|
||||||
def ravel(self, order='C'): return np.ndarray([0, 0])
|
|
||||||
def repeat(self, repeats, axis=None): return np.ndarray([0, 0])
|
|
||||||
def reshape(self, shape, order='C'): return np.ndarray([0, 0])
|
|
||||||
def resize(self, new_shape, refcheck=True): return None
|
|
||||||
def round(self, decimals=0, out=None): return np.ndarray([0, 0])
|
|
||||||
def searchsorted(self, v, side='left', sorter=None): return np.ndarray([0, 0])
|
|
||||||
def setfield(self, val, dtype, offset=0): return None
|
|
||||||
def setflags(self, write=None, align=None, uic=None): return None
|
|
||||||
def sort(self, axis=-1, kind='quicksort', order=None): return None
|
|
||||||
def squeeze(self, axis=None): return np.ndarray([0, 0])
|
|
||||||
def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def sum(self, axis=None, dtype=None, out=None, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def swapaxes(self, axis1, axis2): return np.ndarray([0, 0])
|
|
||||||
def take(self, indices, axis=None, out=None, mode='raise'): return np.ndarray([0, 0])
|
|
||||||
def tobytes(self, order='C'): return b''
|
|
||||||
def tofile(self, fid, sep="", format="%s"): return None
|
|
||||||
def tolist(self, ): return []
|
|
||||||
def tostring(self, order='C'): return b''
|
|
||||||
def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): return np.ndarray([0, 0])
|
|
||||||
def transpose(self, *axes): return np.ndarray([0, 0])
|
|
||||||
def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): return np.ndarray([0, 0])
|
|
||||||
def view(self, dtype=None, type=None): return np.ndarray([0, 0])
|
|
||||||
"""
|
|
||||||
node = astroid.extract_node(ndarray)
|
|
||||||
return node.infer(context=context)
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_numpy_ndarray(node):
|
|
||||||
return isinstance(node, astroid.Attribute) and node.attrname == "ndarray"
|
|
||||||
|
|
||||||
|
|
||||||
astroid.MANAGER.register_transform(
|
|
||||||
astroid.Attribute,
|
|
||||||
astroid.inference_tip(infer_numpy_ndarray),
|
|
||||||
_looks_like_numpy_ndarray,
|
|
||||||
)
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
# Copyright (c) 2019 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
# TODO(hippo91) : correct the functions return types
|
|
||||||
"""Astroid hooks for numpy.random.mtrand module."""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def numpy_random_mtrand_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
def beta(a, b, size=None): return uninferable
|
|
||||||
def binomial(n, p, size=None): return uninferable
|
|
||||||
def bytes(length): return uninferable
|
|
||||||
def chisquare(df, size=None): return uninferable
|
|
||||||
def choice(a, size=None, replace=True, p=None): return uninferable
|
|
||||||
def dirichlet(alpha, size=None): return uninferable
|
|
||||||
def exponential(scale=1.0, size=None): return uninferable
|
|
||||||
def f(dfnum, dfden, size=None): return uninferable
|
|
||||||
def gamma(shape, scale=1.0, size=None): return uninferable
|
|
||||||
def geometric(p, size=None): return uninferable
|
|
||||||
def get_state(): return uninferable
|
|
||||||
def gumbel(loc=0.0, scale=1.0, size=None): return uninferable
|
|
||||||
def hypergeometric(ngood, nbad, nsample, size=None): return uninferable
|
|
||||||
def laplace(loc=0.0, scale=1.0, size=None): return uninferable
|
|
||||||
def logistic(loc=0.0, scale=1.0, size=None): return uninferable
|
|
||||||
def lognormal(mean=0.0, sigma=1.0, size=None): return uninferable
|
|
||||||
def logseries(p, size=None): return uninferable
|
|
||||||
def multinomial(n, pvals, size=None): return uninferable
|
|
||||||
def multivariate_normal(mean, cov, size=None): return uninferable
|
|
||||||
def negative_binomial(n, p, size=None): return uninferable
|
|
||||||
def noncentral_chisquare(df, nonc, size=None): return uninferable
|
|
||||||
def noncentral_f(dfnum, dfden, nonc, size=None): return uninferable
|
|
||||||
def normal(loc=0.0, scale=1.0, size=None): return uninferable
|
|
||||||
def pareto(a, size=None): return uninferable
|
|
||||||
def permutation(x): return uninferable
|
|
||||||
def poisson(lam=1.0, size=None): return uninferable
|
|
||||||
def power(a, size=None): return uninferable
|
|
||||||
def rand(*args): return uninferable
|
|
||||||
def randint(low, high=None, size=None, dtype='l'):
|
|
||||||
import numpy
|
|
||||||
return numpy.ndarray((1,1))
|
|
||||||
def randn(*args): return uninferable
|
|
||||||
def random_integers(low, high=None, size=None): return uninferable
|
|
||||||
def random_sample(size=None): return uninferable
|
|
||||||
def rayleigh(scale=1.0, size=None): return uninferable
|
|
||||||
def seed(seed=None): return uninferable
|
|
||||||
def set_state(state): return uninferable
|
|
||||||
def shuffle(x): return uninferable
|
|
||||||
def standard_cauchy(size=None): return uninferable
|
|
||||||
def standard_exponential(size=None): return uninferable
|
|
||||||
def standard_gamma(shape, size=None): return uninferable
|
|
||||||
def standard_normal(size=None): return uninferable
|
|
||||||
def standard_t(df, size=None): return uninferable
|
|
||||||
def triangular(left, mode, right, size=None): return uninferable
|
|
||||||
def uniform(low=0.0, high=1.0, size=None): return uninferable
|
|
||||||
def vonmises(mu, kappa, size=None): return uninferable
|
|
||||||
def wald(mean, scale, size=None): return uninferable
|
|
||||||
def weibull(a, size=None): return uninferable
|
|
||||||
def zipf(a, size=None): return uninferable
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(
|
|
||||||
astroid.MANAGER, "numpy.random.mtrand", numpy_random_mtrand_transform
|
|
||||||
)
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# Copyright (c) 2019-2020 hippo91 <guillaume.peillex@gmail.com>
|
|
||||||
# Copyright (c) 2019 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Different utilities for the numpy brains"""
|
|
||||||
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def infer_numpy_member(src, node, context=None):
|
|
||||||
node = astroid.extract_node(src)
|
|
||||||
return node.infer(context=context)
|
|
||||||
|
|
||||||
|
|
||||||
def _is_a_numpy_module(node: astroid.node_classes.Name) -> bool:
|
|
||||||
"""
|
|
||||||
Returns True if the node is a representation of a numpy module.
|
|
||||||
|
|
||||||
For example in :
|
|
||||||
import numpy as np
|
|
||||||
x = np.linspace(1, 2)
|
|
||||||
The node <Name.np> is a representation of the numpy module.
|
|
||||||
|
|
||||||
:param node: node to test
|
|
||||||
:return: True if the node is a representation of the numpy module.
|
|
||||||
"""
|
|
||||||
module_nickname = node.name
|
|
||||||
potential_import_target = [
|
|
||||||
x for x in node.lookup(module_nickname)[1] if isinstance(x, astroid.Import)
|
|
||||||
]
|
|
||||||
for target in potential_import_target:
|
|
||||||
if ("numpy", module_nickname) in target.names:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def looks_like_numpy_member(
|
|
||||||
member_name: str, node: astroid.node_classes.NodeNG
|
|
||||||
) -> bool:
|
|
||||||
"""
|
|
||||||
Returns True if the node is a member of numpy whose
|
|
||||||
name is member_name.
|
|
||||||
|
|
||||||
:param member_name: name of the member
|
|
||||||
:param node: node to test
|
|
||||||
:return: True if the node is a member of numpy
|
|
||||||
"""
|
|
||||||
if (
|
|
||||||
isinstance(node, astroid.Attribute)
|
|
||||||
and node.attrname == member_name
|
|
||||||
and isinstance(node.expr, astroid.Name)
|
|
||||||
and _is_a_numpy_module(node.expr)
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
if (
|
|
||||||
isinstance(node, astroid.Name)
|
|
||||||
and node.name == member_name
|
|
||||||
and node.root().name.startswith("numpy")
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
from astroid import parse
|
|
||||||
from astroid import inference_tip
|
|
||||||
from astroid import register_module_extender
|
|
||||||
from astroid import MANAGER
|
|
||||||
|
|
||||||
|
|
||||||
def pkg_resources_transform():
|
|
||||||
return parse(
|
|
||||||
"""
|
|
||||||
def require(*requirements):
|
|
||||||
return pkg_resources.working_set.require(*requirements)
|
|
||||||
|
|
||||||
def run_script(requires, script_name):
|
|
||||||
return pkg_resources.working_set.run_script(requires, script_name)
|
|
||||||
|
|
||||||
def iter_entry_points(group, name=None):
|
|
||||||
return pkg_resources.working_set.iter_entry_points(group, name)
|
|
||||||
|
|
||||||
def resource_exists(package_or_requirement, resource_name):
|
|
||||||
return get_provider(package_or_requirement).has_resource(resource_name)
|
|
||||||
|
|
||||||
def resource_isdir(package_or_requirement, resource_name):
|
|
||||||
return get_provider(package_or_requirement).resource_isdir(
|
|
||||||
resource_name)
|
|
||||||
|
|
||||||
def resource_filename(package_or_requirement, resource_name):
|
|
||||||
return get_provider(package_or_requirement).get_resource_filename(
|
|
||||||
self, resource_name)
|
|
||||||
|
|
||||||
def resource_stream(package_or_requirement, resource_name):
|
|
||||||
return get_provider(package_or_requirement).get_resource_stream(
|
|
||||||
self, resource_name)
|
|
||||||
|
|
||||||
def resource_string(package_or_requirement, resource_name):
|
|
||||||
return get_provider(package_or_requirement).get_resource_string(
|
|
||||||
self, resource_name)
|
|
||||||
|
|
||||||
def resource_listdir(package_or_requirement, resource_name):
|
|
||||||
return get_provider(package_or_requirement).resource_listdir(
|
|
||||||
resource_name)
|
|
||||||
|
|
||||||
def extraction_error():
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_cache_path(archive_name, names=()):
|
|
||||||
extract_path = self.extraction_path or get_default_cache()
|
|
||||||
target_path = os.path.join(extract_path, archive_name+'-tmp', *names)
|
|
||||||
return target_path
|
|
||||||
|
|
||||||
def postprocess(tempname, filename):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_extraction_path(path):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def cleanup_resources(force=False):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_distribution(dist):
|
|
||||||
return Distribution(dist)
|
|
||||||
|
|
||||||
_namespace_packages = {}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
register_module_extender(MANAGER, "pkg_resources", pkg_resources_transform)
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
# Copyright (c) 2014-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2014 Jeff Quast <contact@jeffquast.com>
|
|
||||||
# Copyright (c) 2014 Google, Inc.
|
|
||||||
# Copyright (c) 2016 Florian Bruhin <me@the-compiler.org>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for pytest."""
|
|
||||||
from __future__ import absolute_import
|
|
||||||
from astroid import MANAGER, register_module_extender
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_transform():
|
|
||||||
return AstroidBuilder(MANAGER).string_build(
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _pytest.mark
|
|
||||||
import _pytest.recwarn
|
|
||||||
import _pytest.runner
|
|
||||||
import _pytest.python
|
|
||||||
import _pytest.skipping
|
|
||||||
import _pytest.assertion
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
deprecated_call = _pytest.recwarn.deprecated_call
|
|
||||||
warns = _pytest.recwarn.warns
|
|
||||||
|
|
||||||
exit = _pytest.runner.exit
|
|
||||||
fail = _pytest.runner.fail
|
|
||||||
skip = _pytest.runner.skip
|
|
||||||
importorskip = _pytest.runner.importorskip
|
|
||||||
|
|
||||||
xfail = _pytest.skipping.xfail
|
|
||||||
mark = _pytest.mark.MarkGenerator()
|
|
||||||
raises = _pytest.python.raises
|
|
||||||
|
|
||||||
# New in pytest 3.0
|
|
||||||
try:
|
|
||||||
approx = _pytest.python.approx
|
|
||||||
register_assert_rewrite = _pytest.assertion.register_assert_rewrite
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Moved in pytest 3.0
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _pytest.freeze_support
|
|
||||||
freeze_includes = _pytest.freeze_support.freeze_includes
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
import _pytest.genscript
|
|
||||||
freeze_includes = _pytest.genscript.freeze_includes
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _pytest.debugging
|
|
||||||
set_trace = _pytest.debugging.pytestPDB().set_trace
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
import _pytest.pdb
|
|
||||||
set_trace = _pytest.pdb.pytestPDB().set_trace
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _pytest.fixtures
|
|
||||||
fixture = _pytest.fixtures.fixture
|
|
||||||
yield_fixture = _pytest.fixtures.yield_fixture
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
import _pytest.python
|
|
||||||
fixture = _pytest.python.fixture
|
|
||||||
yield_fixture = _pytest.python.yield_fixture
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
register_module_extender(MANAGER, "pytest", pytest_transform)
|
|
||||||
register_module_extender(MANAGER, "py.test", pytest_transform)
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
# Copyright (c) 2015-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2017 Roy Wright <roy@wright.org>
|
|
||||||
# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk>
|
|
||||||
# Copyright (c) 2019 Antoine Boellinger <aboellinger@hotmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for the PyQT library."""
|
|
||||||
|
|
||||||
from astroid import MANAGER, register_module_extender
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
from astroid import nodes
|
|
||||||
from astroid import parse
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_signal(node, signal_name="pyqtSignal"):
|
|
||||||
if "__class__" in node.instance_attrs:
|
|
||||||
try:
|
|
||||||
cls = node.instance_attrs["__class__"][0]
|
|
||||||
return cls.name == signal_name
|
|
||||||
except AttributeError:
|
|
||||||
# return False if the cls does not have a name attribute
|
|
||||||
pass
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def transform_pyqt_signal(node):
|
|
||||||
module = parse(
|
|
||||||
"""
|
|
||||||
class pyqtSignal(object):
|
|
||||||
def connect(self, slot, type=None, no_receiver_check=False):
|
|
||||||
pass
|
|
||||||
def disconnect(self, slot):
|
|
||||||
pass
|
|
||||||
def emit(self, *args):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
signal_cls = module["pyqtSignal"]
|
|
||||||
node.instance_attrs["emit"] = signal_cls["emit"]
|
|
||||||
node.instance_attrs["disconnect"] = signal_cls["disconnect"]
|
|
||||||
node.instance_attrs["connect"] = signal_cls["connect"]
|
|
||||||
|
|
||||||
|
|
||||||
def transform_pyside_signal(node):
|
|
||||||
module = parse(
|
|
||||||
"""
|
|
||||||
class NotPySideSignal(object):
|
|
||||||
def connect(self, receiver, type=None):
|
|
||||||
pass
|
|
||||||
def disconnect(self, receiver):
|
|
||||||
pass
|
|
||||||
def emit(self, *args):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
signal_cls = module["NotPySideSignal"]
|
|
||||||
node.instance_attrs["connect"] = signal_cls["connect"]
|
|
||||||
node.instance_attrs["disconnect"] = signal_cls["disconnect"]
|
|
||||||
node.instance_attrs["emit"] = signal_cls["emit"]
|
|
||||||
|
|
||||||
|
|
||||||
def pyqt4_qtcore_transform():
|
|
||||||
return AstroidBuilder(MANAGER).string_build(
|
|
||||||
"""
|
|
||||||
|
|
||||||
def SIGNAL(signal_name): pass
|
|
||||||
|
|
||||||
class QObject(object):
|
|
||||||
def emit(self, signal): pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
register_module_extender(MANAGER, "PyQt4.QtCore", pyqt4_qtcore_transform)
|
|
||||||
MANAGER.register_transform(nodes.FunctionDef, transform_pyqt_signal, _looks_like_signal)
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.ClassDef,
|
|
||||||
transform_pyside_signal,
|
|
||||||
lambda node: node.qname() in ("PySide.QtCore.Signal", "PySide2.QtCore.Signal"),
|
|
||||||
)
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
import random
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
from astroid import helpers
|
|
||||||
from astroid import MANAGER
|
|
||||||
|
|
||||||
|
|
||||||
ACCEPTED_ITERABLES_FOR_SAMPLE = (astroid.List, astroid.Set, astroid.Tuple)
|
|
||||||
|
|
||||||
|
|
||||||
def _clone_node_with_lineno(node, parent, lineno):
|
|
||||||
cls = node.__class__
|
|
||||||
other_fields = node._other_fields
|
|
||||||
_astroid_fields = node._astroid_fields
|
|
||||||
init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent}
|
|
||||||
postinit_params = {param: getattr(node, param) for param in _astroid_fields}
|
|
||||||
if other_fields:
|
|
||||||
init_params.update({param: getattr(node, param) for param in other_fields})
|
|
||||||
new_node = cls(**init_params)
|
|
||||||
if hasattr(node, "postinit") and _astroid_fields:
|
|
||||||
new_node.postinit(**postinit_params)
|
|
||||||
return new_node
|
|
||||||
|
|
||||||
|
|
||||||
def infer_random_sample(node, context=None):
|
|
||||||
if len(node.args) != 2:
|
|
||||||
raise astroid.UseInferenceDefault
|
|
||||||
|
|
||||||
length = node.args[1]
|
|
||||||
if not isinstance(length, astroid.Const):
|
|
||||||
raise astroid.UseInferenceDefault
|
|
||||||
if not isinstance(length.value, int):
|
|
||||||
raise astroid.UseInferenceDefault
|
|
||||||
|
|
||||||
inferred_sequence = helpers.safe_infer(node.args[0], context=context)
|
|
||||||
if not inferred_sequence:
|
|
||||||
raise astroid.UseInferenceDefault
|
|
||||||
|
|
||||||
if not isinstance(inferred_sequence, ACCEPTED_ITERABLES_FOR_SAMPLE):
|
|
||||||
raise astroid.UseInferenceDefault
|
|
||||||
|
|
||||||
if length.value > len(inferred_sequence.elts):
|
|
||||||
# In this case, this will raise a ValueError
|
|
||||||
raise astroid.UseInferenceDefault
|
|
||||||
|
|
||||||
try:
|
|
||||||
elts = random.sample(inferred_sequence.elts, length.value)
|
|
||||||
except ValueError:
|
|
||||||
raise astroid.UseInferenceDefault
|
|
||||||
|
|
||||||
new_node = astroid.List(
|
|
||||||
lineno=node.lineno, col_offset=node.col_offset, parent=node.scope()
|
|
||||||
)
|
|
||||||
new_elts = [
|
|
||||||
_clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno)
|
|
||||||
for elt in elts
|
|
||||||
]
|
|
||||||
new_node.postinit(new_elts)
|
|
||||||
return iter((new_node,))
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_random_sample(node):
|
|
||||||
func = node.func
|
|
||||||
if isinstance(func, astroid.Attribute):
|
|
||||||
return func.attrname == "sample"
|
|
||||||
if isinstance(func, astroid.Name):
|
|
||||||
return func.name == "sample"
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
MANAGER.register_transform(
|
|
||||||
astroid.Call, astroid.inference_tip(infer_random_sample), _looks_like_random_sample
|
|
||||||
)
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
import sys
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
PY36 = sys.version_info >= (3, 6)
|
|
||||||
|
|
||||||
if PY36:
|
|
||||||
# Since Python 3.6 there is the RegexFlag enum
|
|
||||||
# where every entry will be exposed via updating globals()
|
|
||||||
|
|
||||||
def _re_transform():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
import sre_compile
|
|
||||||
ASCII = sre_compile.SRE_FLAG_ASCII
|
|
||||||
IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE
|
|
||||||
LOCALE = sre_compile.SRE_FLAG_LOCALE
|
|
||||||
UNICODE = sre_compile.SRE_FLAG_UNICODE
|
|
||||||
MULTILINE = sre_compile.SRE_FLAG_MULTILINE
|
|
||||||
DOTALL = sre_compile.SRE_FLAG_DOTALL
|
|
||||||
VERBOSE = sre_compile.SRE_FLAG_VERBOSE
|
|
||||||
A = ASCII
|
|
||||||
I = IGNORECASE
|
|
||||||
L = LOCALE
|
|
||||||
U = UNICODE
|
|
||||||
M = MULTILINE
|
|
||||||
S = DOTALL
|
|
||||||
X = VERBOSE
|
|
||||||
TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE
|
|
||||||
T = TEMPLATE
|
|
||||||
DEBUG = sre_compile.SRE_FLAG_DEBUG
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "re", _re_transform)
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
"""
|
|
||||||
Astroid hooks for responses.
|
|
||||||
|
|
||||||
It might need to be manually updated from the public methods of
|
|
||||||
:class:`responses.RequestsMock`.
|
|
||||||
|
|
||||||
See: https://github.com/getsentry/responses/blob/master/responses.py
|
|
||||||
|
|
||||||
"""
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def responses_funcs():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
DELETE = "DELETE"
|
|
||||||
GET = "GET"
|
|
||||||
HEAD = "HEAD"
|
|
||||||
OPTIONS = "OPTIONS"
|
|
||||||
PATCH = "PATCH"
|
|
||||||
POST = "POST"
|
|
||||||
PUT = "PUT"
|
|
||||||
response_callback = None
|
|
||||||
|
|
||||||
def reset():
|
|
||||||
return
|
|
||||||
|
|
||||||
def add(
|
|
||||||
method=None, # method or ``Response``
|
|
||||||
url=None,
|
|
||||||
body="",
|
|
||||||
adding_headers=None,
|
|
||||||
*args,
|
|
||||||
**kwargs
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
def add_passthru(prefix):
|
|
||||||
return
|
|
||||||
|
|
||||||
def remove(method_or_response=None, url=None):
|
|
||||||
return
|
|
||||||
|
|
||||||
def replace(method_or_response=None, url=None, body="", *args, **kwargs):
|
|
||||||
return
|
|
||||||
|
|
||||||
def add_callback(
|
|
||||||
method, url, callback, match_querystring=False, content_type="text/plain"
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
calls = []
|
|
||||||
|
|
||||||
def __enter__():
|
|
||||||
return
|
|
||||||
|
|
||||||
def __exit__(type, value, traceback):
|
|
||||||
success = type is None
|
|
||||||
return success
|
|
||||||
|
|
||||||
def activate(func):
|
|
||||||
return func
|
|
||||||
|
|
||||||
def start():
|
|
||||||
return
|
|
||||||
|
|
||||||
def stop(allow_assert=True):
|
|
||||||
return
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "responses", responses_funcs)
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
# Copyright (c) 2019 Valentin Valls <valentin.valls@esrf.fr>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for scipy.signal module."""
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
def scipy_signal():
|
|
||||||
return astroid.parse(
|
|
||||||
"""
|
|
||||||
# different functions defined in scipy.signals
|
|
||||||
|
|
||||||
def barthann(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def bartlett(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def blackman(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def blackmanharris(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def bohman(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def boxcar(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def chebwin(M, at, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def cosine(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def exponential(M, center=None, tau=1.0, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def flattop(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def gaussian(M, std, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def general_gaussian(M, p, sig, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def hamming(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def hann(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def hanning(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def impulse2(system, X0=None, T=None, N=None, **kwargs):
|
|
||||||
return numpy.ndarray([0]), numpy.ndarray([0])
|
|
||||||
|
|
||||||
def kaiser(M, beta, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def nuttall(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def parzen(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def slepian(M, width, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def step2(system, X0=None, T=None, N=None, **kwargs):
|
|
||||||
return numpy.ndarray([0]), numpy.ndarray([0])
|
|
||||||
|
|
||||||
def triang(M, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
|
|
||||||
def tukey(M, alpha=0.5, sym=True):
|
|
||||||
return numpy.ndarray([0])
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "scipy.signal", scipy_signal)
|
|
||||||
|
|
@ -1,201 +0,0 @@
|
||||||
# Copyright (c) 2014-2016, 2018, 2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
|
|
||||||
"""Astroid hooks for six module."""
|
|
||||||
|
|
||||||
from textwrap import dedent
|
|
||||||
|
|
||||||
from astroid import MANAGER, register_module_extender
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
from astroid.exceptions import (
|
|
||||||
AstroidBuildingError,
|
|
||||||
InferenceError,
|
|
||||||
AttributeInferenceError,
|
|
||||||
)
|
|
||||||
from astroid import nodes
|
|
||||||
|
|
||||||
|
|
||||||
SIX_ADD_METACLASS = "six.add_metaclass"
|
|
||||||
|
|
||||||
|
|
||||||
def _indent(text, prefix, predicate=None):
|
|
||||||
"""Adds 'prefix' to the beginning of selected lines in 'text'.
|
|
||||||
|
|
||||||
If 'predicate' is provided, 'prefix' will only be added to the lines
|
|
||||||
where 'predicate(line)' is True. If 'predicate' is not provided,
|
|
||||||
it will default to adding 'prefix' to all non-empty lines that do not
|
|
||||||
consist solely of whitespace characters.
|
|
||||||
"""
|
|
||||||
if predicate is None:
|
|
||||||
predicate = lambda line: line.strip()
|
|
||||||
|
|
||||||
def prefixed_lines():
|
|
||||||
for line in text.splitlines(True):
|
|
||||||
yield prefix + line if predicate(line) else line
|
|
||||||
|
|
||||||
return "".join(prefixed_lines())
|
|
||||||
|
|
||||||
|
|
||||||
_IMPORTS = """
|
|
||||||
import _io
|
|
||||||
cStringIO = _io.StringIO
|
|
||||||
filter = filter
|
|
||||||
from itertools import filterfalse
|
|
||||||
input = input
|
|
||||||
from sys import intern
|
|
||||||
map = map
|
|
||||||
range = range
|
|
||||||
from importlib import reload
|
|
||||||
reload_module = lambda module: reload(module)
|
|
||||||
from functools import reduce
|
|
||||||
from shlex import quote as shlex_quote
|
|
||||||
from io import StringIO
|
|
||||||
from collections import UserDict, UserList, UserString
|
|
||||||
xrange = range
|
|
||||||
zip = zip
|
|
||||||
from itertools import zip_longest
|
|
||||||
import builtins
|
|
||||||
import configparser
|
|
||||||
import copyreg
|
|
||||||
import _dummy_thread
|
|
||||||
import http.cookiejar as http_cookiejar
|
|
||||||
import http.cookies as http_cookies
|
|
||||||
import html.entities as html_entities
|
|
||||||
import html.parser as html_parser
|
|
||||||
import http.client as http_client
|
|
||||||
import http.server as http_server
|
|
||||||
BaseHTTPServer = CGIHTTPServer = SimpleHTTPServer = http.server
|
|
||||||
import pickle as cPickle
|
|
||||||
import queue
|
|
||||||
import reprlib
|
|
||||||
import socketserver
|
|
||||||
import _thread
|
|
||||||
import winreg
|
|
||||||
import xmlrpc.server as xmlrpc_server
|
|
||||||
import xmlrpc.client as xmlrpc_client
|
|
||||||
import urllib.robotparser as urllib_robotparser
|
|
||||||
import email.mime.multipart as email_mime_multipart
|
|
||||||
import email.mime.nonmultipart as email_mime_nonmultipart
|
|
||||||
import email.mime.text as email_mime_text
|
|
||||||
import email.mime.base as email_mime_base
|
|
||||||
import urllib.parse as urllib_parse
|
|
||||||
import urllib.error as urllib_error
|
|
||||||
import tkinter
|
|
||||||
import tkinter.dialog as tkinter_dialog
|
|
||||||
import tkinter.filedialog as tkinter_filedialog
|
|
||||||
import tkinter.scrolledtext as tkinter_scrolledtext
|
|
||||||
import tkinter.simpledialog as tkinder_simpledialog
|
|
||||||
import tkinter.tix as tkinter_tix
|
|
||||||
import tkinter.ttk as tkinter_ttk
|
|
||||||
import tkinter.constants as tkinter_constants
|
|
||||||
import tkinter.dnd as tkinter_dnd
|
|
||||||
import tkinter.colorchooser as tkinter_colorchooser
|
|
||||||
import tkinter.commondialog as tkinter_commondialog
|
|
||||||
import tkinter.filedialog as tkinter_tkfiledialog
|
|
||||||
import tkinter.font as tkinter_font
|
|
||||||
import tkinter.messagebox as tkinter_messagebox
|
|
||||||
import urllib
|
|
||||||
import urllib.request as urllib_request
|
|
||||||
import urllib.robotparser as urllib_robotparser
|
|
||||||
import urllib.parse as urllib_parse
|
|
||||||
import urllib.error as urllib_error
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def six_moves_transform():
|
|
||||||
code = dedent(
|
|
||||||
"""
|
|
||||||
class Moves(object):
|
|
||||||
{}
|
|
||||||
moves = Moves()
|
|
||||||
"""
|
|
||||||
).format(_indent(_IMPORTS, " "))
|
|
||||||
module = AstroidBuilder(MANAGER).string_build(code)
|
|
||||||
module.name = "six.moves"
|
|
||||||
return module
|
|
||||||
|
|
||||||
|
|
||||||
def _six_fail_hook(modname):
|
|
||||||
"""Fix six.moves imports due to the dynamic nature of this
|
|
||||||
class.
|
|
||||||
|
|
||||||
Construct a pseudo-module which contains all the necessary imports
|
|
||||||
for six
|
|
||||||
|
|
||||||
:param modname: Name of failed module
|
|
||||||
:type modname: str
|
|
||||||
|
|
||||||
:return: An astroid module
|
|
||||||
:rtype: nodes.Module
|
|
||||||
"""
|
|
||||||
|
|
||||||
attribute_of = modname != "six.moves" and modname.startswith("six.moves")
|
|
||||||
if modname != "six.moves" and not attribute_of:
|
|
||||||
raise AstroidBuildingError(modname=modname)
|
|
||||||
module = AstroidBuilder(MANAGER).string_build(_IMPORTS)
|
|
||||||
module.name = "six.moves"
|
|
||||||
if attribute_of:
|
|
||||||
# Facilitate import of submodules in Moves
|
|
||||||
start_index = len(module.name)
|
|
||||||
attribute = modname[start_index:].lstrip(".").replace(".", "_")
|
|
||||||
try:
|
|
||||||
import_attr = module.getattr(attribute)[0]
|
|
||||||
except AttributeInferenceError:
|
|
||||||
raise AstroidBuildingError(modname=modname)
|
|
||||||
if isinstance(import_attr, nodes.Import):
|
|
||||||
submodule = MANAGER.ast_from_module_name(import_attr.names[0][0])
|
|
||||||
return submodule
|
|
||||||
# Let dummy submodule imports pass through
|
|
||||||
# This will cause an Uninferable result, which is okay
|
|
||||||
return module
|
|
||||||
|
|
||||||
|
|
||||||
def _looks_like_decorated_with_six_add_metaclass(node):
|
|
||||||
if not node.decorators:
|
|
||||||
return False
|
|
||||||
|
|
||||||
for decorator in node.decorators.nodes:
|
|
||||||
if not isinstance(decorator, nodes.Call):
|
|
||||||
continue
|
|
||||||
if decorator.func.as_string() == SIX_ADD_METACLASS:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def transform_six_add_metaclass(node):
|
|
||||||
"""Check if the given class node is decorated with *six.add_metaclass*
|
|
||||||
|
|
||||||
If so, inject its argument as the metaclass of the underlying class.
|
|
||||||
"""
|
|
||||||
if not node.decorators:
|
|
||||||
return
|
|
||||||
|
|
||||||
for decorator in node.decorators.nodes:
|
|
||||||
if not isinstance(decorator, nodes.Call):
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
func = next(decorator.func.infer())
|
|
||||||
except InferenceError:
|
|
||||||
continue
|
|
||||||
if func.qname() == SIX_ADD_METACLASS and decorator.args:
|
|
||||||
metaclass = decorator.args[0]
|
|
||||||
node._metaclass = metaclass
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
register_module_extender(MANAGER, "six", six_moves_transform)
|
|
||||||
register_module_extender(
|
|
||||||
MANAGER, "requests.packages.urllib3.packages.six", six_moves_transform
|
|
||||||
)
|
|
||||||
MANAGER.register_failed_import_hook(_six_fail_hook)
|
|
||||||
MANAGER.register_transform(
|
|
||||||
nodes.ClassDef,
|
|
||||||
transform_six_add_metaclass,
|
|
||||||
_looks_like_decorated_with_six_add_metaclass,
|
|
||||||
)
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
|
||||||
# Copyright (c) 2019 Benjamin Elven <25181435+S3ntinelX@users.noreply.github.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
"""Astroid hooks for the ssl library."""
|
|
||||||
|
|
||||||
from astroid import MANAGER, register_module_extender
|
|
||||||
from astroid.builder import AstroidBuilder
|
|
||||||
from astroid import nodes
|
|
||||||
from astroid import parse
|
|
||||||
|
|
||||||
|
|
||||||
def ssl_transform():
|
|
||||||
return parse(
|
|
||||||
"""
|
|
||||||
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
|
|
||||||
from _ssl import _SSLContext, MemoryBIO
|
|
||||||
from _ssl import (
|
|
||||||
SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
|
|
||||||
SSLSyscallError, SSLEOFError,
|
|
||||||
)
|
|
||||||
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
|
|
||||||
from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
|
|
||||||
from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
|
|
||||||
try:
|
|
||||||
from _ssl import RAND_egd
|
|
||||||
except ImportError:
|
|
||||||
# LibreSSL does not provide RAND_egd
|
|
||||||
pass
|
|
||||||
from _ssl import (OP_ALL, OP_CIPHER_SERVER_PREFERENCE,
|
|
||||||
OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3,
|
|
||||||
OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2,
|
|
||||||
OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE)
|
|
||||||
|
|
||||||
from _ssl import (ALERT_DESCRIPTION_ACCESS_DENIED, ALERT_DESCRIPTION_BAD_CERTIFICATE,
|
|
||||||
ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE,
|
|
||||||
ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE,
|
|
||||||
ALERT_DESCRIPTION_BAD_RECORD_MAC,
|
|
||||||
ALERT_DESCRIPTION_CERTIFICATE_EXPIRED,
|
|
||||||
ALERT_DESCRIPTION_CERTIFICATE_REVOKED,
|
|
||||||
ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN,
|
|
||||||
ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE,
|
|
||||||
ALERT_DESCRIPTION_CLOSE_NOTIFY, ALERT_DESCRIPTION_DECODE_ERROR,
|
|
||||||
ALERT_DESCRIPTION_DECOMPRESSION_FAILURE,
|
|
||||||
ALERT_DESCRIPTION_DECRYPT_ERROR,
|
|
||||||
ALERT_DESCRIPTION_HANDSHAKE_FAILURE,
|
|
||||||
ALERT_DESCRIPTION_ILLEGAL_PARAMETER,
|
|
||||||
ALERT_DESCRIPTION_INSUFFICIENT_SECURITY,
|
|
||||||
ALERT_DESCRIPTION_INTERNAL_ERROR,
|
|
||||||
ALERT_DESCRIPTION_NO_RENEGOTIATION,
|
|
||||||
ALERT_DESCRIPTION_PROTOCOL_VERSION,
|
|
||||||
ALERT_DESCRIPTION_RECORD_OVERFLOW,
|
|
||||||
ALERT_DESCRIPTION_UNEXPECTED_MESSAGE,
|
|
||||||
ALERT_DESCRIPTION_UNKNOWN_CA,
|
|
||||||
ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY,
|
|
||||||
ALERT_DESCRIPTION_UNRECOGNIZED_NAME,
|
|
||||||
ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE,
|
|
||||||
ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION,
|
|
||||||
ALERT_DESCRIPTION_USER_CANCELLED)
|
|
||||||
from _ssl import (SSL_ERROR_EOF, SSL_ERROR_INVALID_ERROR_CODE, SSL_ERROR_SSL,
|
|
||||||
SSL_ERROR_SYSCALL, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_READ,
|
|
||||||
SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_X509_LOOKUP, SSL_ERROR_ZERO_RETURN)
|
|
||||||
from _ssl import VERIFY_CRL_CHECK_CHAIN, VERIFY_CRL_CHECK_LEAF, VERIFY_DEFAULT, VERIFY_X509_STRICT
|
|
||||||
from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
|
|
||||||
from _ssl import _OPENSSL_API_VERSION
|
|
||||||
from _ssl import PROTOCOL_SSLv23, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2
|
|
||||||
from _ssl import PROTOCOL_TLS, PROTOCOL_TLS_CLIENT, PROTOCOL_TLS_SERVER
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
register_module_extender(MANAGER, "ssl", ssl_transform)
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
# Copyright (c) 2016-2020 Claudiu Popa <pcmanticore@gmail.com>
|
|
||||||
# Copyright (c) 2017 Hugo <hugovk@users.noreply.github.com>
|
|
||||||
# Copyright (c) 2018 Peter Talley <peterctalley@gmail.com>
|
|
||||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
|
||||||
# Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com>
|
|
||||||
|
|
||||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
|
||||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
import astroid
|
|
||||||
|
|
||||||
|
|
||||||
PY37 = sys.version_info >= (3, 7)
|
|
||||||
PY36 = sys.version_info >= (3, 6)
|
|
||||||
|
|
||||||
|
|
||||||
def _subprocess_transform():
|
|
||||||
communicate = (bytes("string", "ascii"), bytes("string", "ascii"))
|
|
||||||
communicate_signature = "def communicate(self, input=None, timeout=None)"
|
|
||||||
if PY37:
|
|
||||||
init = """
|
|
||||||
def __init__(self, args, bufsize=0, executable=None,
|
|
||||||
stdin=None, stdout=None, stderr=None,
|
|
||||||
preexec_fn=None, close_fds=False, shell=False,
|
|
||||||
cwd=None, env=None, universal_newlines=False,
|
|
||||||
startupinfo=None, creationflags=0, restore_signals=True,
|
|
||||||
start_new_session=False, pass_fds=(), *,
|
|
||||||
encoding=None, errors=None, text=None):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
elif PY36:
|
|
||||||
init = """
|
|
||||||
def __init__(self, args, bufsize=0, executable=None,
|
|
||||||
stdin=None, stdout=None, stderr=None,
|
|
||||||
preexec_fn=None, close_fds=False, shell=False,
|
|
||||||
cwd=None, env=None, universal_newlines=False,
|
|
||||||
startupinfo=None, creationflags=0, restore_signals=True,
|
|
||||||
start_new_session=False, pass_fds=(), *,
|
|
||||||
encoding=None, errors=None):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
init = """
|
|
||||||
def __init__(self, args, bufsize=0, executable=None,
|
|
||||||
stdin=None, stdout=None, stderr=None,
|
|
||||||
preexec_fn=None, close_fds=False, shell=False,
|
|
||||||
cwd=None, env=None, universal_newlines=False,
|
|
||||||
startupinfo=None, creationflags=0, restore_signals=True,
|
|
||||||
start_new_session=False, pass_fds=()):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
wait_signature = "def wait(self, timeout=None)"
|
|
||||||
ctx_manager = """
|
|
||||||
def __enter__(self): return self
|
|
||||||
def __exit__(self, *args): pass
|
|
||||||
"""
|
|
||||||
py3_args = "args = []"
|
|
||||||
|
|
||||||
if PY37:
|
|
||||||
check_output_signature = """
|
|
||||||
check_output(
|
|
||||||
args, *,
|
|
||||||
stdin=None,
|
|
||||||
stderr=None,
|
|
||||||
shell=False,
|
|
||||||
cwd=None,
|
|
||||||
encoding=None,
|
|
||||||
errors=None,
|
|
||||||
universal_newlines=False,
|
|
||||||
timeout=None,
|
|
||||||
env=None,
|
|
||||||
text=None,
|
|
||||||
restore_signals=True,
|
|
||||||
preexec_fn=None,
|
|
||||||
pass_fds=(),
|
|
||||||
input=None,
|
|
||||||
start_new_session=False
|
|
||||||
):
|
|
||||||
""".strip()
|
|
||||||
else:
|
|
||||||
check_output_signature = """
|
|
||||||
check_output(
|
|
||||||
args, *,
|
|
||||||
stdin=None,
|
|
||||||
stderr=None,
|
|
||||||
shell=False,
|
|
||||||
cwd=None,
|
|
||||||
encoding=None,
|
|
||||||
errors=None,
|
|
||||||
universal_newlines=False,
|
|
||||||
timeout=None,
|
|
||||||
env=None,
|
|
||||||
restore_signals=True,
|
|
||||||
preexec_fn=None,
|
|
||||||
pass_fds=(),
|
|
||||||
input=None,
|
|
||||||
start_new_session=False
|
|
||||||
):
|
|
||||||
""".strip()
|
|
||||||
|
|
||||||
code = textwrap.dedent(
|
|
||||||
"""
|
|
||||||
def %(check_output_signature)s
|
|
||||||
if universal_newlines:
|
|
||||||
return ""
|
|
||||||
return b""
|
|
||||||
|
|
||||||
class Popen(object):
|
|
||||||
returncode = pid = 0
|
|
||||||
stdin = stdout = stderr = file()
|
|
||||||
%(py3_args)s
|
|
||||||
|
|
||||||
%(communicate_signature)s:
|
|
||||||
return %(communicate)r
|
|
||||||
%(wait_signature)s:
|
|
||||||
return self.returncode
|
|
||||||
def poll(self):
|
|
||||||
return self.returncode
|
|
||||||
def send_signal(self, signal):
|
|
||||||
pass
|
|
||||||
def terminate(self):
|
|
||||||
pass
|
|
||||||
def kill(self):
|
|
||||||
pass
|
|
||||||
%(ctx_manager)s
|
|
||||||
"""
|
|
||||||
% {
|
|
||||||
"check_output_signature": check_output_signature,
|
|
||||||
"communicate": communicate,
|
|
||||||
"communicate_signature": communicate_signature,
|
|
||||||
"wait_signature": wait_signature,
|
|
||||||
"ctx_manager": ctx_manager,
|
|
||||||
"py3_args": py3_args,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
init_lines = textwrap.dedent(init).splitlines()
|
|
||||||
indented_init = "\n".join(" " * 4 + line for line in init_lines)
|
|
||||||
code += indented_init
|
|
||||||
return astroid.parse(code)
|
|
||||||
|
|
||||||
|
|
||||||
astroid.register_module_extender(astroid.MANAGER, "subprocess", _subprocess_transform)
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue