diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index d3684924cc..5ceb5d1f20 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -51,7 +51,7 @@ jobs: - name: Test for Mac Deps cache hit id: macdep-cache - uses: actions/cache@v4.1.2 + uses: actions/cache@v4.2.0 with: path: ${{ github.workspace }}/pygame_mac_deps_${{ matrix.macarch }} # The hash of all files in buildconfig manylinux-build and macdependencies is @@ -118,14 +118,14 @@ jobs: - uses: actions/checkout@v4.2.2 - name: pip cache - uses: actions/cache@v4.1.2 + uses: actions/cache@v4.2.0 with: path: ~/Library/Caches/pip # This cache path is only right on mac key: pip-cache-${{ matrix.macarch }}-${{ matrix.os }} - name: Fetch Mac deps id: macdep-cache - uses: actions/cache@v4.1.2 + uses: actions/cache@v4.2.0 with: path: ${{ github.workspace }}/pygame_mac_deps_${{ matrix.macarch }} key: macdep-${{ hashFiles('buildconfig/manylinux-build/**') }}-${{ hashFiles('buildconfig/macdependencies/*.sh') }}-${{ matrix.macarch }} diff --git a/.github/workflows/build-sdl3.yml b/.github/workflows/build-sdl3.yml index 066439e04e..7b2cfe9987 100644 --- a/.github/workflows/build-sdl3.yml +++ b/.github/workflows/build-sdl3.yml @@ -86,6 +86,17 @@ jobs: cmake --build . --config Release --parallel sudo cmake --install . --config Release + - name: Install SDL3_image + if: matrix.os != 'windows-latest' + run: | + git clone https://github.com/libsdl-org/SDL_image + cd SDL_image + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release .. + cmake --build . --config Release --parallel + sudo cmake --install . --config Release + - name: Build with SDL3 run: python3 dev.py build --sdl3 diff --git a/.github/workflows/build-ubuntu-sdist.yml b/.github/workflows/build-ubuntu-sdist.yml index c58b9d8a6c..64ec5ef716 100644 --- a/.github/workflows/build-ubuntu-sdist.yml +++ b/.github/workflows/build-ubuntu-sdist.yml @@ -84,7 +84,7 @@ jobs: - name: Test typestubs run: | - pip3 install mypy + pip3 install mypy==1.13.0 python3 buildconfig/stubs/stubcheck.py # We upload the generated files under github actions assets diff --git a/.github/workflows/release-gh-draft.yml b/.github/workflows/release-gh-draft.yml index c56e9d3bfd..0f5acc8f22 100644 --- a/.github/workflows/release-gh-draft.yml +++ b/.github/workflows/release-gh-draft.yml @@ -61,7 +61,7 @@ jobs: run: echo "VER=${GITHUB_REF_NAME#'release/'}" >> $GITHUB_OUTPUT - name: Generate release attestation - uses: actions/attest-build-provenance@v1.4.4 + uses: actions/attest-build-provenance@v2.1.0 with: subject-path: "pygame-wheels/*" diff --git a/buildconfig/download_win_prebuilt.py b/buildconfig/download_win_prebuilt.py index aa12faca0f..9c56e007f6 100644 --- a/buildconfig/download_win_prebuilt.py +++ b/buildconfig/download_win_prebuilt.py @@ -78,16 +78,20 @@ def get_urls(x86=True, x64=True): url_sha1 = [] url_sha1.extend([ [ - 'https://github.com/libsdl-org/SDL/releases/download/release-2.30.9/SDL2-devel-2.30.9-VC.zip', - 'd89a2ad46b98ba08db5ec5877cb2fde46e127825', + 'https://github.com/libsdl-org/SDL/releases/download/release-2.30.10/SDL2-devel-2.30.10-VC.zip', + '42378fd090d547d03dca8c9df584ba8f38555809', ], [ 'https://github.com/libsdl-org/SDL/releases/download/preview-3.1.6/SDL3-devel-3.1.6-VC.zip', '7a3b9ed85cfe735c7e106d98c4b6395a113e5d7e' ], [ - 'https://github.com/pygame-community/SDL_image/releases/download/2.8.2-pgce/SDL2_image-devel-2.8.2-VCpgce.zip', - '983484dd816abf25cdd5bce88ac69dbca1ea713a' + 'https://github.com/pygame-community/SDL_image/releases/download/2.8.3-pgce/SDL2_image-devel-2.8.3-VCpgce.zip', + '71ad2b5aacbc934a39e390ad733421313dd5d059' + ], + [ + 'https://github.com/libsdl-org/SDL_image/releases/download/preview-3.1.0/SDL3_image-devel-3.1.0-VC.zip', + '8538fea0cc4aabba2fc64db06196f1bb76a2785f' ], [ 'https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.22.0/SDL2_ttf-devel-2.22.0-VC.zip', @@ -205,14 +209,26 @@ def copy(src, dst): copy( os.path.join( temp_dir, - 'SDL2_image-devel-2.8.2-VCpgce/SDL2_image-2.8.2' + 'SDL2_image-devel-2.8.3-VCpgce/SDL2_image-2.8.3' + ), + os.path.join( + move_to_dir, + prebuilt_dir, + 'SDL2_image-2.8.3' + ) + ) + copy( + os.path.join( + temp_dir, + 'SDL3_image-devel-3.1.0-VC/SDL3_image-3.1.0' ), os.path.join( move_to_dir, prebuilt_dir, - 'SDL2_image-2.8.2' + 'SDL3_image-3.1.0' ) ) + copy( os.path.join( temp_dir, @@ -238,12 +254,12 @@ def copy(src, dst): copy( os.path.join( temp_dir, - 'SDL2-devel-2.30.9-VC/SDL2-2.30.9' + 'SDL2-devel-2.30.10-VC/SDL2-2.30.10' ), os.path.join( move_to_dir, prebuilt_dir, - 'SDL2-2.30.9' + 'SDL2-2.30.10' ) ) copy( diff --git a/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh b/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh index d0546b18bb..7d6da64605 100644 --- a/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh +++ b/buildconfig/manylinux-build/docker_base/sdl_libs/build-sdl2-libs.sh @@ -3,9 +3,9 @@ set -e -x cd $(dirname `readlink -f "$0"`) -SDL2_VER="2.30.9" +SDL2_VER="2.30.10" SDL2="SDL2-$SDL2_VER" -IMG2_VER="2.8.2" +IMG2_VER="2.8.3" IMG2="SDL2_image-$IMG2_VER" TTF2_VER="2.22.0" TTF2="SDL2_ttf-$TTF2_VER" diff --git a/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 b/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 index 2cae1f3830..8d171a1031 100644 --- a/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 +++ b/buildconfig/manylinux-build/docker_base/sdl_libs/sdl2.sha512 @@ -1,4 +1,4 @@ -30dfa86fcced174fef0ed78ffa53476a31765e19cdcdf8233ab92876445b4dedaa758fc42a3ec332324d13faa2daafcadcc44fc0f536a2969ef836162ec3cd36 SDL2-2.30.9.tar.gz -0ff345824f95158dfa72f83f9d4a540601c178cd759334bf849c14a2920b5330d0763413b58c08b3deba8d3a4ccb6ea2a8159f87efe4cbb0e8ea850f63d09454 SDL2_image-2.8.2.tar.gz +bcb220749cd3b0874288d617419e622701138bcb8fe55e9b665e8843c65afda031d01afe0d11e308a9608724ed151f342e5f5670c84204b36943cb323ced41da SDL2-2.30.10.tar.gz +b49e466494a4bebcacc09e3fe2afbe5edbae636c007cd26e7e04301bf8fe54db6751258b750a79656e5aa261869900d39703f1311df4c63ef415ae443f62295f SDL2_image-2.8.3.tar.gz 5ddbc4b0b5fad2e0844a503daa79564b912654192599ef8fa7698531f08323ce01801f6bb17b2b3905020a3df362a967b7566ae725eb085da991578cc0807aad SDL2_mixer-2.8.0.tar.gz 34a1d210d8f1b1e802139d65ba47e36033bb7881e75a8862c1b1c515565bef85e3d81ee42e952aa664de043debef387ba60088a9cf3ba3297413db39a13af912 SDL2_ttf-2.22.0.tar.gz diff --git a/buildconfig/stubs/pygame/__init__.pyi b/buildconfig/stubs/pygame/__init__.pyi index e1e404ed37..16ed10de2a 100644 --- a/buildconfig/stubs/pygame/__init__.pyi +++ b/buildconfig/stubs/pygame/__init__.pyi @@ -111,6 +111,7 @@ from .constants import ( BLENDMODE_ADD as BLENDMODE_ADD, BLENDMODE_BLEND as BLENDMODE_BLEND, BLENDMODE_MOD as BLENDMODE_MOD, + BLENDMODE_MUL as BLENDMODE_MUL, BLENDMODE_NONE as BLENDMODE_NONE, BLEND_ADD as BLEND_ADD, BLEND_ALPHA_SDL2 as BLEND_ALPHA_SDL2, diff --git a/buildconfig/stubs/pygame/constants.pyi b/buildconfig/stubs/pygame/constants.pyi index 463f2509c8..2c4f5030f9 100644 --- a/buildconfig/stubs/pygame/constants.pyi +++ b/buildconfig/stubs/pygame/constants.pyi @@ -34,6 +34,7 @@ BIG_ENDIAN: int BLENDMODE_ADD: int BLENDMODE_BLEND: int BLENDMODE_MOD: int +BLENDMODE_MUL: int BLENDMODE_NONE: int BLEND_ADD: int BLEND_ALPHA_SDL2: int diff --git a/buildconfig/stubs/pygame/display.pyi b/buildconfig/stubs/pygame/display.pyi index 5124e92b47..43e1ec8c05 100644 --- a/buildconfig/stubs/pygame/display.pyi +++ b/buildconfig/stubs/pygame/display.pyi @@ -44,14 +44,16 @@ def set_mode( display: int = 0, vsync: int = 0, ) -> Surface: ... -def get_surface() -> Surface: ... +def get_surface() -> Optional[Surface]: ... def flip() -> None: ... @overload +def update() -> None: ... +@overload def update( - rectangle: Optional[Union[RectLike, Iterable[Optional[RectLike]]]] = None, / + rectangle: Optional[Union[RectLike, Iterable[Optional[RectLike]]]], / ) -> None: ... @overload -def update(x: int, y: int, w: int, h: int, /) -> None: ... +def update(x: float, y: float, w: float, h: float, /) -> None: ... @overload def update(xy: Point, wh: Point, /) -> None: ... def get_driver() -> str: ... diff --git a/buildconfig/stubs/pygame/locals.pyi b/buildconfig/stubs/pygame/locals.pyi index e596355311..b1d3a99093 100644 --- a/buildconfig/stubs/pygame/locals.pyi +++ b/buildconfig/stubs/pygame/locals.pyi @@ -34,6 +34,7 @@ BIG_ENDIAN: int BLENDMODE_ADD: int BLENDMODE_BLEND: int BLENDMODE_MOD: int +BLENDMODE_MUL: int BLENDMODE_NONE: int BLEND_ADD: int BLEND_ALPHA_SDL2: int diff --git a/buildconfig/stubs/stubcheck.py b/buildconfig/stubs/stubcheck.py index d0c544a4c8..fba1938f73 100644 --- a/buildconfig/stubs/stubcheck.py +++ b/buildconfig/stubs/stubcheck.py @@ -49,7 +49,7 @@ def stubs_check(): continue cmd = " ".join(stubtest) - print(f"Using stubtest invokation: `{cmd}` (version: {version})") + print(f"Using stubtest invocation: `{cmd}` (version: {version})") prev_dir = os.getcwd() try: os.chdir(STUBS_BASE_DIR) diff --git a/dev.py b/dev.py index c7a5dfb29e..7695f7eba0 100644 --- a/dev.py +++ b/dev.py @@ -26,7 +26,6 @@ SDL3_ARGS = [ "-Csetup-args=-Dsdl_api=3", - "-Csetup-args=-Dimage=disabled", "-Csetup-args=-Dmixer=disabled", "-Csetup-args=-Dfont=disabled", ] diff --git a/docs/reST/ref/display.rst b/docs/reST/ref/display.rst index 310ebb38fa..223a3744de 100644 --- a/docs/reST/ref/display.rst +++ b/docs/reST/ref/display.rst @@ -251,6 +251,7 @@ required). | :sl:`Get a reference to the currently set display surface` | :sg:`get_surface() -> Surface` + | :sg:`get_surface() -> None` Return a reference to the currently set display Surface. If no display mode has been set this will return None. @@ -272,7 +273,10 @@ required). .. function:: update | :sl:`Update all, or a portion, of the display. For non-OpenGL displays.` - | :sg:`update(rectangle=None, /) -> None` + | :sg:`update() -> None` + | :sg:`update(rectangle, /) -> None` + | :sg:`update(x, y, w, h, /) -> None` + | :sg:`update((x, y), (w, h), /) -> None` | :sg:`update(rectangle_iterable, /) -> None` For non OpenGL display Surfaces, this function is very similar to diff --git a/docs/reST/ref/draw.rst b/docs/reST/ref/draw.rst index 53f5c35b44..01f39e4f4c 100644 --- a/docs/reST/ref/draw.rst +++ b/docs/reST/ref/draw.rst @@ -492,7 +492,7 @@ object around the draw calls (see :func:`pygame.Surface.lock` and .. versionchangedold:: 2.0.0 Added support for keyword arguments. .. versionchanged:: 2.4.0 Removed deprecated 'blend' argument - .. versionchanged:: 2.5.0 ``blend`` argument readded for backcompat, but will always raise a deprecation exception when used + .. versionchanged:: 2.5.0 ``blend`` argument re-added for backcompat, but will always raise a deprecation exception when used .. versionchanged:: 2.5.3 Added line width .. ## pygame.draw.aaline ## @@ -533,7 +533,7 @@ object around the draw calls (see :func:`pygame.Surface.lock` and .. versionchangedold:: 2.0.0 Added support for keyword arguments. .. versionchanged:: 2.4.0 Removed deprecated ``blend`` argument - .. versionchanged:: 2.5.0 ``blend`` argument readded for backcompat, but will always raise a deprecation exception when used + .. versionchanged:: 2.5.0 ``blend`` argument re-added for backcompat, but will always raise a deprecation exception when used .. ## pygame.draw.aalines ## diff --git a/docs/reST/ref/image.rst b/docs/reST/ref/image.rst index 65438a9e82..e851ccdf0e 100644 --- a/docs/reST/ref/image.rst +++ b/docs/reST/ref/image.rst @@ -245,7 +245,7 @@ following formats. .. note:: The use of this function is recommended over :func:`tostring` as of pygame 2.1.3. This function was introduced so it matches nicely with other - libraries (PIL, numpy, etc), and with people's expectations. + libraries (PIL, NumPy, etc), and with people's expectations. .. versionadded:: 2.1.3 .. versionchanged:: 2.2.0 Now supports keyword arguments. @@ -290,7 +290,7 @@ following formats. .. note:: The use of this function is recommended over :func:`fromstring` as of pygame 2.1.3. This function was introduced so it matches nicely with other - libraries (PIL, numpy, etc), and with people's expectations. + libraries (PIL, NumPy, etc), and with people's expectations. .. versionadded:: 2.1.3 .. versionadded:: 2.1.4 Added a 'pitch' argument and support for keyword arguments. diff --git a/docs/reST/ref/mixer.rst b/docs/reST/ref/mixer.rst index 76d1122772..0558fb62fa 100644 --- a/docs/reST/ref/mixer.rst +++ b/docs/reST/ref/mixer.rst @@ -9,9 +9,7 @@ | :sl:`pygame module for loading and playing sounds` This module contains classes for loading Sound objects and controlling -playback. The mixer module is optional and depends on SDL_mixer. Your program -should test that :mod:`pygame.mixer` is available and initialized before using -it. +playback. The mixer module has a limited number of channels for playback of sounds. Usually programs tell pygame to start playing audio and it selects an available @@ -30,9 +28,7 @@ streams the music from the files without loading music at once into memory. The mixer module must be initialized like other pygame modules, but it has some extra conditions. The ``pygame.mixer.init()`` function takes several optional -arguments to control the playback rate and sample size. Pygame will default to -reasonable values, but pygame cannot perform Sound resampling, so the mixer -should be initialized to match the values of your audio resources. +arguments to control the playback rate and sample size. ``NOTE``: For less laggy sound use a smaller buffer size. The default is set to reduce the chance of scratchy sounds on some computers. You can @@ -91,7 +87,7 @@ The following file formats are supported the next nearest power of 2). The devicename parameter is the name of sound device to open for audio - playback. Allowed device names will vary based on the host system. + playback. Allowed device names will vary based on the host system. If left as ``None`` then a sensible default will be chosen for you. Some platforms require the :mod:`pygame.mixer` module to be initialized @@ -331,7 +327,7 @@ The following file formats are supported :rtype: tuple .. note:: - The linked and compile version numbers should be the same. + The linked and compiled version numbers should be the same. .. versionaddedold:: 2.0.0 @@ -368,7 +364,7 @@ The following file formats are supported it and the Sound object. For now buffer and array support is consistent with ``sndarray.make_sound`` - for Numeric arrays, in that sample sign and byte order are ignored. This + for NumPy arrays, in that sample sign and byte order are ignored. This will change, either by correctly handling sign and byte order, or by raising an exception when different. Also, source samples are truncated to fit the audio sample size. This will not change. diff --git a/docs/reST/ref/sndarray.rst b/docs/reST/ref/sndarray.rst index bc2899f614..75dbd1b21b 100644 --- a/docs/reST/ref/sndarray.rst +++ b/docs/reST/ref/sndarray.rst @@ -62,6 +62,7 @@ one. DEPRECATED: Uses the requested array type for the module functions. The only supported arraytype is ``'numpy'``. Other values will raise ValueError. Using this function will raise a ``DeprecationWarning``. + .. ## pygame.sndarray.use_arraytype ## .. function:: get_arraytype diff --git a/docs/reST/ref/surface.rst b/docs/reST/ref/surface.rst index 7153dc7fd3..06c14b2e83 100644 --- a/docs/reST/ref/surface.rst +++ b/docs/reST/ref/surface.rst @@ -205,7 +205,7 @@ object and dest is its destination position on this Surface. It draws each source Surface fully (meaning that unlike `blit()` you cannot pass an "area" parameter to represent a smaller portion of the source Surface to draw) on this Surface with the same blending - mode specified by special_flags. The sequence must have at least one (source, dest) pair. + mode specified by special_flags. :param blit_sequence: a sequence of (source, dest) :param special_flags: the flag(s) representing the blend mode used for each surface. diff --git a/docs/reST/ref/surfarray.rst b/docs/reST/ref/surfarray.rst index 48b917fbfd..9b56a0dfb8 100644 --- a/docs/reST/ref/surfarray.rst +++ b/docs/reST/ref/surfarray.rst @@ -30,7 +30,7 @@ specific pixel value of a color. Integer pixel values can only be used directly between surfaces with matching pixel layouts (see :class:`pygame.Surface`). All functions that refer to "array" will copy the surface information to a new -numpy array. All functions that refer to "pixels" will directly reference the +NumPy array. All functions that refer to "pixels" will directly reference the pixels from the surface and any changes performed to the array will make changes in the surface. As this last functions share memory with the surface, this one will be locked during the lifetime of the array. diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index af81d53267..b460047bd7 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -291,7 +291,7 @@ .. attribute:: utility - | :sl:`Get if the windos is an utility window (**read-only**)` + | :sl:`Get if the window is an utility window (**read-only**)` | :sg:`utility -> bool` ``True`` if the window doesn't appear in the task bar, ``False`` otherwise. diff --git a/docs/readmes/README.zh-tw.rst b/docs/readmes/README.zh-tw.rst new file mode 100644 index 0000000000..30cbb6d6eb --- /dev/null +++ b/docs/readmes/README.zh-tw.rst @@ -0,0 +1,180 @@ +.. image:: https://raw.githubusercontent.com/pygame-community/pygame-ce/main/docs/reST/_static/pygame_ce_logo.svg + :alt: pygame + :target: https://pyga.me/ + + +|DocsStatus| +|PyPiVersion| |PyPiLicense| +|Python3| |GithubCommits| |BlackFormatBadge| + +`English`_ `简体中文`_ **繁體中文** `Français`_ `فارسی`_ `Español`_ +---- + +Pygame_ 是一款自由且開源的跨平台程式庫,用於開發電子遊戲等多媒體應用。Pygame基於 `Simple DirectMedia Layer library`_ 以及其他幾個廣受歡迎的程式庫,提取其中最常見的函數,讓編寫遊戲成為更符合直覺的事情。 + +本發行版名為 **“pygame - Community Edition“** (簡稱 “pygame-ce“)。 + +pygame-ce是上游pygame專案的分支,由此前pygame專案的核心開發者創建。開發者們在上游的開發中受到了強烈的阻撓,無法繼續,所以創建了這個發行版。新的發行版主旨在提供更頻繁的版本更新,持續不斷的bug修復與功能增強,以及更民主的管理模式。 + +歡迎新的貢獻者加入我們。 + +安装 +------------ + +:: + + pip install pygame-ce + + +入門 +---- + +剛接觸pygame的初學者應該可以快速入門。pygame提供了大量教學與介紹,也提供了整個函式庫的完整參考文件。你可以在 `docs page`_ 瀏覽文件。也可以在終端機中執行`python -m pygame.docs`,在本機瀏覽文件。如果找不到本機文檔,會自動開啟線上文檔。 + +線上文件與github中的開發版pygame同步。文件版本可能比你正在使用的pygame版本新一些。在終端機中執行 ``pip install pygame-ce --upgrade`` 可以升級到最新完整版本。 + +最重要的是,examples目錄中有許多可以玩的小程序,可以讓你立即開啟程式碼之旅。 + +從原始碼開始編譯 +-------------------- + +如果你想使用那些正在開發的特性,或者你想要為pygame做出貢獻,你需要從原始碼開始編譯pygame,而不是用pip來安裝。 + +編譯與安裝的流程是高度自動化的。你要做的工作主要是pygame依賴的編譯與安裝。一旦完成,你就可以執行`setup.py`,它會嘗試完成自動配置,編譯,然後安裝pygame。 + +更多關於編譯與安裝訊息,請參閱 `Compilation wiki page`_ 。 + + + +鳴謝 +------- + +感謝為本資源庫貢獻的每一個人。 + +特別鳴謝: + +* Marcus Von Appen: many changes, and fixes, 1.7.1+ freebsd maintainer +* Lenard Lindstrom: the 1.8+ windows maintainer, many changes, and fixes +* Brian Fisher for svn auto builder, bug tracker and many contributions +* Rene Dudfield: many changes, and fixes, 1.7+ release manager/maintainer +* Phil Hassey for his work on the pygame.org website +* DR0ID for his work on the sprite module +* Richard Goedeken for his smoothscale function +* Ulf Ekström for his pixel perfect collision detection code +* Pete Shinners: original author +* David Clark for filling the right-hand-man position +* Ed Boraas and Francis Irving: Debian packages +* Maxim Sobolev: FreeBSD packaging +* Bob Ippolito: macOS and OS X porting (much work!) +* Jan Ekhol, Ray Kelm, and Peter Nicolai: putting up with early design ideas +* Nat Pryce for starting our unit tests +* Dan Richter for documentation work +* TheCorruptor for his incredible logos and graphics +* Nicholas Dudfield: many test improvements +* Alex Folkner for pygame-ctypes + +感謝發送補丁/修復的人:Niki Spahiev, Gordon +Tyler, Nathaniel Pryce, Dave Wallace, John Popplewell, Michael Urman, +Andrew Straw, Michael Hudson, Ole Martin Bjoerndalen, Herve Cauwelier, +James Mazer, Lalo Martins, Timothy Stranex, Chad Lester, Matthias +Spiller, Bo Jangeborg, Dmitry Borisov, Campbell Barton, Diego Essaya, +Eyal Lotem, Regis Desgroppes, Emmanuel Hainry, Randy Kaelber, +Matthew L Daniel, Nirav Patel, Forrest Voight, Charlie Nolan, +Frankie Robertson, John Krukoff, Lorenz Quack, Nick Irvine, +Michael George, Saul Spatz, Thomas Ibbotson, Tom Rothamel, Evan Kroske, +Cambell Barton. + +以及我們卓越的bug獵人:Angus, Guillaume Proux, Frank +Raiser, Austin Henry, Kaweh Kazemi, Arturo Aldama, Mike Mulcheck, +Michael Benfield, David Lau + +還有許多人提交了有用的想法,助力本計畫前進,使我們的生活變得更加輕鬆。感謝你們! + +非常感謝人們提出文件評論並添加到 pygame 文件和 pygame-ce 文檔 + +感謝製作遊戲並把遊戲放到pygame.org網站供人學習與娛樂的人。 + +感謝 James Paige 建立了pygame bugzilla。 + +感謝 Roger Dingledine 與SEUL.ORG上的crew,感謝我們優秀的主持。 + +依賴 +------------ + + +pygame顯然依賴SDL和Python。此外pygame也嵌入了幾個較小的函式庫:font模組依賴SDL_ttf(SDL_ttf依賴freetype);mixer模組(以及mixer.music模組)依賴SDL_mixer;image模組依賴SDL_image(SDL_image使用到libjpeg與libpng) ;transform模組內嵌了一個SDL_rotozoom來實現它的rotozoom函式;surfarray模組用到了Numpy中的多維數組。 + +依賴的版本要求如下: + + + ++----------+------------------------+ +| CPython | >= 3.9 (或 PyPy3) | ++----------+------------------------+ +| SDL | >= 2.0.14 | ++----------+------------------------+ +| SDL_mixer| >= 2.0.4 | ++----------+------------------------+ +| SDL_image| >= 2.0.4 | ++----------+------------------------+ +| SDL_ttf | >= 2.0.15 | ++----------+------------------------+ + + +如何貢獻 +-------- + +首先,感謝你考慮為 pygame-ce 做出貢獻!正是像你這樣的人讓 pygame-ce 成為一個偉大的函式庫。請依照以下步驟開始: + +1. 閱讀 `Contribution Guidelines`_ 和 `Many Ways to Contribute`_ wiki 頁面。 +2. 閱讀 `Opening A Pull Request`_ 和 `Opening a Great Pull Request`_ 的相關文件。 +3. 學習How to `label and link reported issues`_ 。 +4. 檢查 `issue tracker`_ 以查找你有興趣的issue,或建立一個新的issue來開始討論你的想法。 + +`wiki pages`_ 上還有許多資源可以幫助你入門。 + +如果有任何問題,請隨時在 `Pygame Community Discord Server`_ 詢問或建立一個issue。 + + +授權條款 +------- +**授權條款版本:** LGPL-2.1-or-later + +本函式庫在 `GNU LGPL version 2.1`_ 下發布,許可文件: ``docs/LGPL.txt`` 。我們保留將此函式庫的未來版本置於其他許可證下的權利。 + +這基本上代表你可以在任意專案中使用pygame,但如果你修改或增加了pygame庫的內容,這些內容必須使用原授權條款相容的授權發布(我們更希望修改者將其提交回pygame專案)。閉源或商業性遊戲中可以使用pygame。 + +``examples`` 目錄中的程式不受版權限制。 + +有關依賴相的許可證,請參閱 ``docs/licenses`` 。 + + + +.. |PyPiVersion| image:: https://img.shields.io/pypi/v/pygame-ce.svg?v=1 + :target: https://pypi.python.org/pypi/pygame-ce + +.. |PyPiLicense| image:: https://img.shields.io/pypi/l/pygame-ce.svg?v=1 + :target: https://pypi.python.org/pypi/pygame-ce + +.. |Python3| image:: https://img.shields.io/badge/python-3-blue.svg?v=1 + +.. |GithubCommits| image:: https://img.shields.io/github/commits-since/pygame-community/pygame-ce/2.3.0.svg + :target: https://github.com/pygame-community/pygame-ce/compare/2.3.0...main + +.. |DocsStatus| image:: https://img.shields.io/website?down_message=offline&label=docs&up_message=online&url=https%3A%2F%2Fpyga.me%2Fdocs%2F + :target: https://pyga.me/docs/ + +.. |BlackFormatBadge| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + +.. _pygame: https://www.pyga.me +.. _Simple DirectMedia Layer library: https://www.libsdl.org +.. _Compilation wiki page: https://github.com/pygame-community/pygame-ce/wiki#compiling +.. _docs page: https://pyga.me/docs +.. _GNU LGPL version 2.1: https://www.gnu.org/copyleft/lesser.html + +.. _English: ./../../README.rst +.. _简体中文: README.zh-cn.rst +.. _Français: README.fr.rst +.. _فارسی: README.fa.rst +.. _Español: README.es.rst diff --git a/examples/ninepatch.py b/examples/ninepatch.py index ccdac7dc4f..375a1b7970 100644 --- a/examples/ninepatch.py +++ b/examples/ninepatch.py @@ -44,7 +44,7 @@ def ninepatch_scale( ) # when alpha is False the flags become 0 # aliases - ret_w, ret_h = size # non-sequence argument catched by python + ret_w, ret_h = size # non-sequence argument caught by python src_w, src_h = surface.size c = corner_size scale_func = pygame.transform.smoothscale if smooth else pygame.transform.scale diff --git a/meson.build b/meson.build index 318de28b1f..7b8017c390 100644 --- a/meson.build +++ b/meson.build @@ -109,8 +109,8 @@ if plat == 'win' and host_machine.cpu_family().startswith('x86') ) endif - sdl_ver = (sdl_api == 3) ? '3.1.6' : '2.30.9' - sdl_image_ver = '2.8.2' + sdl_ver = (sdl_api == 3) ? '3.1.6' : '2.30.10' + sdl_image_ver = (sdl_api == 3) ? '3.1.0' : '2.8.3' sdl_mixer_ver = '2.8.0' sdl_ttf_ver = '2.22.0' @@ -131,12 +131,18 @@ if plat == 'win' and host_machine.cpu_family().startswith('x86') pg_lib_dirs += sdl_image_lib_dir dlls += [ sdl_image_lib_dir / '@0@.dll'.format(sdl_image), - sdl_image_lib_dir / 'optional' / 'libjpeg-62.dll', - sdl_image_lib_dir / 'optional' / 'libpng16-16.dll', - sdl_image_lib_dir / 'optional' / 'libtiff-5.dll', + sdl_image_lib_dir / 'optional' / (sdl_api == 3 ? 'libtiff-6.dll' : 'libtiff-5.dll'), sdl_image_lib_dir / 'optional' / 'libwebp-7.dll', sdl_image_lib_dir / 'optional' / 'libwebpdemux-2.dll', ] + # temporary solution to get things compiling under SDL3_image. In the future + # we would want to have libpng and libjpeg on SDL3_image as well. + if sdl_api != 3 + dlls += [ + sdl_image_lib_dir / 'optional' / 'libjpeg-62.dll', + sdl_image_lib_dir / 'optional' / 'libpng16-16.dll', + ] + endif endif # SDL_mixer diff --git a/src_c/_sdl2/controller.c b/src_c/_sdl2/controller.c index 331ffd876d..648af64a09 100644 --- a/src_c/_sdl2/controller.c +++ b/src_c/_sdl2/controller.c @@ -159,7 +159,7 @@ controller_attached(pgControllerObject *self, PyObject *_null) { CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } return PyBool_FromLong(SDL_GameControllerGetAttached(self->controller)); @@ -171,7 +171,7 @@ controller_as_joystick(pgControllerObject *self, PyObject *_null) CONTROLLER_INIT_CHECK(); JOYSTICK_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } return pgJoystick_New(self->id); @@ -188,7 +188,7 @@ controller_get_axis(pgControllerObject *self, PyObject *args, PyObject *kwargs) } CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } if (axis < 0 || axis > SDL_CONTROLLER_AXIS_MAX - 1) { @@ -210,7 +210,7 @@ controller_get_button(pgControllerObject *self, PyObject *args, } CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } if (button < 0 || button > SDL_CONTROLLER_BUTTON_MAX) { @@ -230,7 +230,7 @@ controller_get_mapping(pgControllerObject *self, PyObject *_null) CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } mapping = SDL_GameControllerMapping(self->controller); @@ -285,7 +285,7 @@ controller_set_mapping(pgControllerObject *self, PyObject *args, CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } char guid_str[64]; @@ -364,7 +364,7 @@ controller_rumble(pgControllerObject *self, PyObject *args, PyObject *kwargs) CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } // rumble takes values in range 0 to 0xFFFF (65535) @@ -382,7 +382,7 @@ controller_stop_rumble(pgControllerObject *self, PyObject *_null) { CONTROLLER_INIT_CHECK(); if (!self->controller) { - return RAISE(pgExc_SDLError, "Controller is not initalized"); + return RAISE(pgExc_SDLError, "Controller is not initialized"); } SDL_GameControllerRumble(self->controller, 0, 0, 1); Py_RETURN_NONE; diff --git a/src_c/base.c b/src_c/base.c index f42b045783..b07f18e4e3 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -496,24 +496,19 @@ pg_base_get_init(PyObject *self, PyObject *_null) static int pg_IntFromObj(PyObject *obj, int *val) { - int tmp_val; - if (PyFloat_Check(obj)) { /* Python3.8 complains with deprecation warnings if we pass * floats to PyLong_AsLong. */ - double dv = PyFloat_AsDouble(obj); - tmp_val = (int)dv; + *val = (int)PyFloat_AS_DOUBLE(obj); } else { - tmp_val = PyLong_AsLong(obj); - } - - if (tmp_val == -1 && PyErr_Occurred()) { - PyErr_Clear(); - return 0; + *val = PyLong_AsLong(obj); + if (*val == -1 && PyErr_Occurred()) { + PyErr_Clear(); + return 0; + } } - *val = tmp_val; return 1; } @@ -535,30 +530,79 @@ pg_IntFromObjIndex(PyObject *obj, int _index, int *val) static int pg_TwoIntsFromObj(PyObject *obj, int *val1, int *val2) { - if (PyTuple_Check(obj) && PyTuple_Size(obj) == 1) { + // First, lets check the size. This returns -1 if invalid and may set an + // error. + Py_ssize_t obj_size = PySequence_Size(obj); + + // If the object is a tuple of one element, try that one element. + if (obj_size == 1 && PyTuple_Check(obj)) { return pg_TwoIntsFromObj(PyTuple_GET_ITEM(obj, 0), val1, val2); } - if (!PySequence_Check(obj) || PySequence_Length(obj) != 2) { + + // Otherwise lets make sure this is a legit sequence and has two elements. + // Some objects can passing PySequence_Size but fail PySequence_Check + // (like sets) + if (obj_size != 2 || !PySequence_Check(obj)) { + PyErr_Clear(); // Clear the potential error from PySequence_Size + return 0; + } + + // Now we can extract the items, using this macro because we know + // obj is a PySequence. + PyObject *item1 = PySequence_ITEM(obj, 0); + PyObject *item2 = PySequence_ITEM(obj, 1); + + // If either item is NULL lets get out of here + if (item1 == NULL || item2 == NULL) { + Py_XDECREF(item1); + Py_XDECREF(item2); + PyErr_Clear(); return 0; } - if (!pg_IntFromObjIndex(obj, 0, val1) || - !pg_IntFromObjIndex(obj, 1, val2)) { + + // Fastest way to extract numbers I tested (in Python 3.13) is to extract + // Python floats as doubles with the below macro, and get everything else + // through PyLong_AsLong, using C casting to turn into the final type. + if (PyFloat_Check(item1)) { + *val1 = (int)PyFloat_AS_DOUBLE(item1); + } + else { + *val1 = PyLong_AsLong(item1); + } + + if (PyFloat_Check(item2)) { + *val2 = (int)PyFloat_AS_DOUBLE(item2); + } + else { + *val2 = PyLong_AsLong(item2); + } + + // This catches the case where either of the PyLong_AsLong's failed + if ((*val1 == -1 || *val2 == -1) && PyErr_Occurred()) { + PyErr_Clear(); + Py_DECREF(item1); + Py_DECREF(item2); return 0; } + + Py_DECREF(item1); + Py_DECREF(item2); return 1; } static int pg_FloatFromObj(PyObject *obj, float *val) { - float f = (float)PyFloat_AsDouble(obj); - - if (f == -1 && PyErr_Occurred()) { - PyErr_Clear(); - return 0; + if (PyFloat_Check(obj)) { + *val = (float)PyFloat_AS_DOUBLE(obj); + } + else { + *val = (float)PyLong_AsLong(obj); + if (*val == -1.0f && PyErr_Occurred()) { + PyErr_Clear(); + return 0; + } } - - *val = f; return 1; } @@ -580,16 +624,63 @@ pg_FloatFromObjIndex(PyObject *obj, int _index, float *val) static int pg_TwoFloatsFromObj(PyObject *obj, float *val1, float *val2) { - if (PyTuple_Check(obj) && PyTuple_Size(obj) == 1) { + // First, lets check the size. This returns -1 if invalid and may set an + // error. + Py_ssize_t obj_size = PySequence_Size(obj); + + // If the object is a tuple of one element, try that one element. + if (obj_size == 1 && PyTuple_Check(obj)) { return pg_TwoFloatsFromObj(PyTuple_GET_ITEM(obj, 0), val1, val2); } - if (!PySequence_Check(obj) || PySequence_Length(obj) != 2) { + + // Otherwise lets make sure this is a legit sequence and has two elements. + // Some objects can passing PySequence_Size but fail PySequence_Check + // (like sets) + if (obj_size != 2 || !PySequence_Check(obj)) { + PyErr_Clear(); // Clear the potential error from PySequence_Size + return 0; + } + + // Now we can extract the items, using this macro because we know + // obj is a PySequence. + PyObject *item1 = PySequence_ITEM(obj, 0); + PyObject *item2 = PySequence_ITEM(obj, 1); + + // If either item is NULL lets get out of here + if (item1 == NULL || item2 == NULL) { + Py_XDECREF(item1); + Py_XDECREF(item2); + PyErr_Clear(); return 0; } - if (!pg_FloatFromObjIndex(obj, 0, val1) || - !pg_FloatFromObjIndex(obj, 1, val2)) { + + // Fastest way to extract numbers I tested (in Python 3.13) is to extract + // Python floats as doubles with the below macro, and get everything else + // through PyLong_AsLong, using C casting to turn into the final type. + if (PyFloat_Check(item1)) { + *val1 = (float)PyFloat_AS_DOUBLE(item1); + } + else { + *val1 = (float)PyLong_AsLong(item1); + } + + if (PyFloat_Check(item2)) { + *val2 = (float)PyFloat_AS_DOUBLE(item2); + } + else { + *val2 = (float)PyLong_AsLong(item2); + } + + // This catches the case where either of the PyLong_AsLong's failed + if ((*val1 == -1.0f || *val2 == -1.0f) && PyErr_Occurred()) { + PyErr_Clear(); + Py_DECREF(item1); + Py_DECREF(item2); return 0; } + + Py_DECREF(item1); + Py_DECREF(item2); return 1; } diff --git a/src_c/constants.c b/src_c/constants.c index 771aefca5a..04b8e0771d 100644 --- a/src_c/constants.c +++ b/src_c/constants.c @@ -160,6 +160,7 @@ MODINIT_DEFINE(constants) DEC_CONST(BLENDMODE_BLEND); DEC_CONST(BLENDMODE_ADD); DEC_CONST(BLENDMODE_MOD); + DEC_CONST(BLENDMODE_MUL); DEC_CONST(GL_STEREO); DEC_CONST(GL_MULTISAMPLEBUFFERS); DEC_CONST(GL_MULTISAMPLESAMPLES); diff --git a/src_c/cython/pygame/_sdl2/video.pxd b/src_c/cython/pygame/_sdl2/video.pxd index 8d3d868286..1d87ba43b2 100644 --- a/src_c/cython/pygame/_sdl2/video.pxd +++ b/src_c/cython/pygame/_sdl2/video.pxd @@ -107,6 +107,7 @@ cdef extern from "SDL.h" nogil: SDL_BLENDMODE_BLEND = 0x00000001, SDL_BLENDMODE_ADD = 0x00000002, SDL_BLENDMODE_MOD = 0x00000004, + SDL_BLENDMODE_MUL = 0x00000008, SDL_BLENDMODE_INVALID = 0x7FFFFFFF # https://wiki.libsdl.org/SDL_MessageBoxData diff --git a/src_c/doc/display_doc.h b/src_c/doc/display_doc.h index 17b881bd49..8e03e368fe 100644 --- a/src_c/doc/display_doc.h +++ b/src_c/doc/display_doc.h @@ -4,9 +4,9 @@ #define DOC_DISPLAY_QUIT "quit() -> None\nUninitialize the display module" #define DOC_DISPLAY_GETINIT "get_init() -> bool\nReturns True if the display module has been initialized" #define DOC_DISPLAY_SETMODE "set_mode(size=(0, 0), flags=0, depth=0, display=0, vsync=0) -> Surface\nInitialize a window or screen for display" -#define DOC_DISPLAY_GETSURFACE "get_surface() -> Surface\nGet a reference to the currently set display surface" +#define DOC_DISPLAY_GETSURFACE "get_surface() -> Surface\nget_surface() -> None\nGet a reference to the currently set display surface" #define DOC_DISPLAY_FLIP "flip() -> None\nUpdate the full display Surface to the screen" -#define DOC_DISPLAY_UPDATE "update(rectangle=None, /) -> None\nupdate(rectangle_iterable, /) -> None\nUpdate all, or a portion, of the display. For non-OpenGL displays." +#define DOC_DISPLAY_UPDATE "update() -> None\nupdate(rectangle, /) -> None\nupdate(x, y, w, h, /) -> None\nupdate((x, y), (w, h), /) -> None\nupdate(rectangle_iterable, /) -> None\nUpdate all, or a portion, of the display. For non-OpenGL displays." #define DOC_DISPLAY_GETDRIVER "get_driver() -> name\nGet the name of the pygame display backend" #define DOC_DISPLAY_INFO "Info() -> VideoInfo\nCreate a video display information object" #define DOC_DISPLAY_GETWMINFO "get_wm_info() -> dict\nGet information about the current windowing system" diff --git a/src_c/doc/window_doc.h b/src_c/doc/window_doc.h index bed2a7cd27..8a1063a54b 100644 --- a/src_c/doc/window_doc.h +++ b/src_c/doc/window_doc.h @@ -17,7 +17,7 @@ #define DOC_WINDOW_POSITION "position -> (int, int) or WINDOWPOS_CENTERED or WINDOWPOS_UNDEFINED\nGet or set the window position in screen coordinates" #define DOC_WINDOW_OPACITY "opacity -> float\nGet or set the window opacity, between 0.0 (fully transparent) and 1.0 (fully opaque)" #define DOC_WINDOW_OPENGL "opengl -> bool\nGet if the window supports OpenGL" -#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the windos is an utility window (**read-only**)" +#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the window is an utility window (**read-only**)" #define DOC_WINDOW_FROMDISPLAYMODULE "from_display_module() -> Window\nCreate a Window object using window data from display module" #define DOC_WINDOW_GETSURFACE "get_surface() -> Surface\nGet the window surface" #define DOC_WINDOW_FLIP "flip() -> None\nUpdate the display surface to the window." diff --git a/src_c/imageext.c b/src_c/imageext.c index d2823fcb00..bb5873c5d7 100644 --- a/src_c/imageext.c +++ b/src_c/imageext.c @@ -46,7 +46,15 @@ #include "pgopengl.h" +#ifdef PG_SDL3 +#include + +// SDL3_images uses SDL3 error reporting API +#define IMG_GetError SDL_GetError +#else #include +#endif + #ifdef WIN32 #define strcasecmp _stricmp #else diff --git a/src_c/meson.build b/src_c/meson.build index bb94eddcb2..c8eb46677b 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -407,9 +407,6 @@ endif # optional modules -# TODO: support SDL3 -if sdl_api != 3 - if sdl_image_dep.found() imageext = py.extension_module( 'imageext', @@ -421,6 +418,9 @@ if sdl_image_dep.found() ) endif +# TODO: support SDL3 +if sdl_api != 3 + if sdl_ttf_dep.found() font = py.extension_module( 'font', diff --git a/src_c/simd_transform_avx2.c b/src_c/simd_transform_avx2.c index 2cd0a81bbb..18c27ac355 100644 --- a/src_c/simd_transform_avx2.c +++ b/src_c/simd_transform_avx2.c @@ -165,7 +165,7 @@ grayscale_avx2(SDL_Surface *src, SDL_Surface *newsurf) mm256_dst = _mm256_hadd_epi16(mm256_dstA, mm256_dstB); mm256_dst = _mm256_add_epi16(mm256_dst, _mm256_srli_epi32(mm256_dst, 16)); - // Shuffle the gray value from ther first channel of each pixel + // Shuffle the gray value from the first channel of each pixel // into every channel of each pixel mm256_dst = _mm256_shuffle_epi8(mm256_dst, mm256_shuff_mask_gray); diff --git a/src_c/window.c b/src_c/window.c index aec40e8688..8934898d4d 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -835,7 +835,7 @@ window_init(pgWindowObject *self, PyObject *args, PyObject *kwargs) const char *_key_str; int _value_bool; - // ensure display is init at this point, diplay init automatically calls + // ensure display is init at this point, display init automatically calls // the window init in this module if (!pg_mod_autoinit(IMPPREFIX "display")) return -1; @@ -1071,7 +1071,7 @@ window_from_display_module(PyTypeObject *cls, PyObject *_null) return NULL; } - // ensure display is init at this point, diplay init automatically calls + // ensure display is init at this point, display init automatically calls // the window init in this module if (!pg_mod_autoinit(IMPPREFIX "display")) return NULL; diff --git a/test/surfarray_test.py b/test/surfarray_test.py index 2288f9b862..bfcf8f15fe 100644 --- a/test/surfarray_test.py +++ b/test/surfarray_test.py @@ -13,6 +13,7 @@ rint, arange, __version__ as np_version, + array, ) import pygame @@ -487,17 +488,19 @@ def do_blit(surf, arr): # this test should be removed soon, when the function is deleted def test_get_arraytype(self): - array_type = pygame.surfarray.get_arraytype() + with self.assertWarns(DeprecationWarning): + array_type = pygame.surfarray.get_arraytype() - self.assertEqual(array_type, "numpy", f"unknown array type {array_type}") + self.assertEqual(array_type, "numpy", f"unknown array type {array_type}") # this test should be removed soon, when the function is deleted def test_get_arraytypes(self): - arraytypes = pygame.surfarray.get_arraytypes() - self.assertIn("numpy", arraytypes) + with self.assertWarns(DeprecationWarning): + arraytypes = pygame.surfarray.get_arraytypes() + self.assertIn("numpy", arraytypes) - for atype in arraytypes: - self.assertEqual(atype, "numpy", f"unknown array type {atype}") + for atype in arraytypes: + self.assertEqual(atype, "numpy", f"unknown array type {atype}") def test_make_surface(self): # How does one properly test this with 2d arrays. It makes no sense @@ -711,24 +714,23 @@ def test_use_arraytype(self): def do_use_arraytype(atype): pygame.surfarray.use_arraytype(atype) - pygame.surfarray.use_arraytype("numpy") - self.assertEqual(pygame.surfarray.get_arraytype(), "numpy") - self.assertRaises(ValueError, do_use_arraytype, "not an option") + with self.assertWarns(DeprecationWarning): + pygame.surfarray.use_arraytype("numpy") + self.assertEqual(pygame.surfarray.get_arraytype(), "numpy") + self.assertRaises(ValueError, do_use_arraytype, "not an option") def test_surf_lock(self): sf = pygame.Surface((5, 5), 0, 32) - for atype in pygame.surfarray.get_arraytypes(): - pygame.surfarray.use_arraytype(atype) - ar = pygame.surfarray.pixels2d(sf) - self.assertTrue(sf.get_locked()) + ar = pygame.surfarray.pixels2d(sf) + self.assertTrue(sf.get_locked()) - sf.unlock() - self.assertTrue(sf.get_locked()) + sf.unlock() + self.assertTrue(sf.get_locked()) - del ar - self.assertFalse(sf.get_locked()) - self.assertEqual(sf.get_locks(), ()) + del ar + self.assertFalse(sf.get_locked()) + self.assertEqual(sf.get_locks(), ()) if __name__ == "__main__": diff --git a/test/test_utils/test_machinery.py b/test/test_utils/test_machinery.py index 0531cc2f71..068e52df9c 100644 --- a/test/test_utils/test_machinery.py +++ b/test/test_utils/test_machinery.py @@ -44,7 +44,7 @@ def getTestCaseNames(self, testCaseClass): TAGS_RE = re.compile(r"\|[tT]ags:(-?[ a-zA-Z,0-9_\n]+)\|", re.M) -class TestTags: +class TheTestTags: def __init__(self): self.memoized = {} self.parent_modules = {} @@ -86,4 +86,4 @@ def __call__(self, parent_class, meth): return self.memoized[key] -get_tags = TestTags() +get_tags = TheTestTags()