Merge branch 'release/1.10.x'

This commit is contained in:
rdb 2023-10-13 23:24:48 +02:00
commit e01cb590de
21 changed files with 291 additions and 106 deletions

View File

@ -355,6 +355,23 @@ jobs:
rmdir panda3d-1.10.14
(cd thirdparty/darwin-libs-a && rm -rf rocket)
- name: Set up Python 3.12
if: matrix.os != 'windows-2019'
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Build Python 3.12
if: matrix.os != 'windows-2019'
shell: bash
run: |
python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10
- name: Test Python 3.12
if: matrix.os != 'windows-2019'
shell: bash
run: |
python -m pip install -r requirements-test.txt
PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:

View File

@ -2650,11 +2650,11 @@ class main(wx.Frame):
for inputFile in inputs:
if (inputFile != ''):
inputFilename = inputFile.split('\\')[-1]
print "Compare: ", inFile, filename, inputFile, inputFilename
print("Compare: ", inFile, filename, inputFile, inputFilename)
if inputFilename == filename:
inputTime = os.path.getmtime(inputFile)
outputTime = os.path.getmtime(inFile)
print "Matched: ", (inputTime > outputTime)
print("Matched: ", (inputTime > outputTime))
inputChanged = (inputTime > outputTime)
break
'''
@ -2848,7 +2848,7 @@ class main(wx.Frame):
except ValueError:
return
#print self.batchList
#print(self.batchList)
def OnBatchItemEdit(self, event):
selectedItemId = self.batchTree.GetSelections()

View File

@ -1,4 +1,4 @@
from distutils.core import setup
from setuptools import setup
import py2exe
setup(console=['Panda3DToolsGUI.py'])

View File

@ -5,7 +5,6 @@ import modulefinder
import sys
import os
import marshal
import imp
import platform
import struct
import io
@ -13,6 +12,7 @@ import sysconfig
import zipfile
import importlib
import warnings
from importlib import machinery
from . import pefile
@ -24,6 +24,16 @@ except ImportError:
from panda3d.core import Filename, Multifile, PandaSystem, StringStream
# Old imp constants.
_PY_SOURCE = 1
_PY_COMPILED = 2
_C_EXTENSION = 3
_PKG_DIRECTORY = 5
_C_BUILTIN = 6
_PY_FROZEN = 7
_PKG_NAMESPACE_DIRECTORY = object()
# Check to see if we are running python_d, which implies we have a
# debug build, and we have to build the module with debug options.
# This is only relevant on Windows.
@ -37,7 +47,7 @@ isDebugBuild = (python.lower().endswith('_d'))
# NB. if encodings are removed, be sure to remove them from the shortcut in
# deploy-stub.c.
startupModules = [
'imp', 'encodings', 'encodings.*', 'io', 'marshal', 'importlib.machinery',
'encodings', 'encodings.*', 'io', 'marshal', 'importlib.machinery',
'importlib.util',
]
@ -262,10 +272,15 @@ class CompilationEnvironment:
self.arch = '-arch x86_64'
elif proc in ('arm64', 'aarch64'):
self.arch = '-arch arm64'
self.compileObjExe = "gcc -c %(arch)s -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
self.compileObjDll = "gcc -fPIC -c %(arch)s -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
self.linkExe = "gcc %(arch)s -o %(basename)s %(basename)s.o -framework Python"
self.linkDll = "gcc %(arch)s -undefined dynamic_lookup -bundle -o %(basename)s.so %(basename)s.o"
self.compileObjExe = "clang -c %(arch)s -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
self.compileObjDll = "clang -fPIC -c %(arch)s -o %(basename)s.o -O2 -I%(pythonIPath)s %(filename)s"
self.linkExe = "clang %(arch)s -o %(basename)s %(basename)s.o"
if '/Python.framework/' in self.PythonIPath:
framework_dir = self.PythonIPath.split("/Python.framework/", 1)[0]
if framework_dir != "/System/Library/Frameworks":
self.linkExe += " -F " + framework_dir
self.linkExe += " -framework Python"
self.linkDll = "clang %(arch)s -undefined dynamic_lookup -bundle -o %(basename)s.so %(basename)s.o"
else:
# Unix
@ -897,12 +912,11 @@ class Freezer:
# Suffix/extension for Python C extension modules
if self.platform == PandaSystem.getPlatform():
suffixes = imp.get_suffixes()
# Set extension for Python files to binary mode
for i, suffix in enumerate(suffixes):
if suffix[2] == imp.PY_SOURCE:
suffixes[i] = (suffix[0], 'rb', imp.PY_SOURCE)
suffixes = (
[(s, 'rb', _C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES] +
[(s, 'rb', _PY_SOURCE) for s in machinery.SOURCE_SUFFIXES] +
[(s, 'rb', _PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
)
else:
suffixes = [('.py', 'rb', 1), ('.pyc', 'rb', 2)]
@ -1316,10 +1330,10 @@ class Freezer:
ext = mdef.filename.getExtension()
if ext == 'pyc' or ext == 'pyo':
fp = open(pathname, 'rb')
stuff = ("", "rb", imp.PY_COMPILED)
stuff = ("", "rb", _PY_COMPILED)
self.mf.load_module(mdef.moduleName, fp, pathname, stuff)
else:
stuff = ("", "rb", imp.PY_SOURCE)
stuff = ("", "rb", _PY_SOURCE)
if mdef.text:
fp = io.StringIO(mdef.text)
else:
@ -1415,7 +1429,7 @@ class Freezer:
def __addPyc(self, multifile, filename, code, compressionLevel):
if code:
data = imp.get_magic() + b'\0\0\0\0\0\0\0\0'
data = importlib.util.MAGIC_NUMBER + b'\0\0\0\0\0\0\0\0'
data += marshal.dumps(code)
stream = StringStream(data)
@ -1605,7 +1619,7 @@ class Freezer:
# trouble importing it as a builtin module. Synthesize a frozen
# module that loads it as builtin.
if '.' in moduleName and self.linkExtensionModules:
code = compile('import sys;del sys.modules["%s"];import imp;imp.init_builtin("%s")' % (moduleName, moduleName), moduleName, 'exec', optimize=self.optimize)
code = compile('import sys;del sys.modules["%s"];from importlib._bootstrap import _builtin_from_name;_builtin_from_name("%s")' % (moduleName, moduleName), moduleName, 'exec', optimize=self.optimize)
code = marshal.dumps(code)
mangledName = self.mangleName(moduleName)
moduleDefs.append(self.makeModuleDef(mangledName, code))
@ -1887,9 +1901,19 @@ class Freezer:
if '.' in moduleName and not self.platform.startswith('android'):
if self.platform.startswith("macosx") and not use_console:
# We write the Frameworks directory to sys.path[0].
code = 'import sys;del sys.modules["%s"];import sys,os,imp;imp.load_dynamic("%s",os.path.join(sys.path[0], "%s%s"))' % (moduleName, moduleName, moduleName, modext)
direxpr = 'sys.path[0]'
else:
code = 'import sys;del sys.modules["%s"];import sys,os,imp;imp.load_dynamic("%s",os.path.join(os.path.dirname(sys.executable), "%s%s"))' % (moduleName, moduleName, moduleName, modext)
direxpr = 'os.path.dirname(sys.executable)'
code = \
f'import sys;' \
f'del sys.modules["{moduleName}"];' \
f'import sys,os;' \
f'from importlib.machinery import ExtensionFileLoader,ModuleSpec;' \
f'from importlib._bootstrap import _load;' \
f'path=os.path.join({direxpr}, "{moduleName}{modext}");' \
f'_load(ModuleSpec(name="{moduleName}", loader=ExtensionFileLoader("{moduleName}", path), origin=path))'
code = compile(code, moduleName, 'exec', optimize=self.optimize)
code = marshal.dumps(code)
moduleList.append((moduleName, len(pool), len(code)))
@ -2400,9 +2424,6 @@ class Freezer:
return True
_PKG_NAMESPACE_DIRECTORY = object()
class PandaModuleFinder(modulefinder.ModuleFinder):
def __init__(self, *args, **kw):
@ -2415,7 +2436,12 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
self.builtin_module_names = kw.pop('builtin_module_names', sys.builtin_module_names)
self.suffixes = kw.pop('suffixes', imp.get_suffixes())
self.suffixes = kw.pop('suffixes', (
[(s, 'rb', _C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES] +
[(s, 'r', _PY_SOURCE) for s in machinery.SOURCE_SUFFIXES] +
[(s, 'rb', _PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
))
self.optimize = kw.pop('optimize', -1)
modulefinder.ModuleFinder.__init__(self, *args, **kw)
@ -2563,7 +2589,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
suffix, mode, type = file_info
self.msgin(2, "load_module", fqname, fp and "fp", pathname)
if type == imp.PKG_DIRECTORY:
if type == _PKG_DIRECTORY:
m = self.load_package(fqname, pathname)
self.msgout(2, "load_module ->", m)
return m
@ -2574,7 +2600,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
m.__path__ = pathname
return m
if type == imp.PY_SOURCE:
if type == _PY_SOURCE:
if fqname in overrideModules:
# This module has a custom override.
code = overrideModules[fqname]
@ -2598,7 +2624,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
code += b'\n' if isinstance(code, bytes) else '\n'
co = compile(code, pathname, 'exec', optimize=self.optimize)
elif type == imp.PY_COMPILED:
elif type == _PY_COMPILED:
if sys.version_info >= (3, 7):
try:
data = fp.read()
@ -2752,11 +2778,11 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
# If we have a custom override for this module, we know we have it.
if fullname in overrideModules:
return (None, '', ('.py', 'r', imp.PY_SOURCE))
return (None, '', ('.py', 'r', _PY_SOURCE))
# It's built into the interpreter.
if fullname in self.builtin_module_names:
return (None, None, ('', '', imp.C_BUILTIN))
return (None, None, ('', '', _C_BUILTIN))
# If no search path is given, look for a built-in module.
if path is None:
@ -2806,7 +2832,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
for suffix, mode, _ in self.suffixes:
init = os.path.join(basename, '__init__' + suffix)
if self._open_file(init, mode):
return (None, basename, ('', '', imp.PKG_DIRECTORY))
return (None, basename, ('', '', _PKG_DIRECTORY))
# This may be a namespace package.
if self._dir_exists(basename):
@ -2818,7 +2844,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
# Only if we're not looking on a particular path, though.
if p3extend_frozen and p3extend_frozen.is_frozen_module(name):
# It's a frozen module.
return (None, name, ('', '', imp.PY_FROZEN))
return (None, name, ('', '', _PY_FROZEN))
# If we found folders on the path with this module name without an
# __init__.py file, we should consider this a namespace package.

View File

@ -13,7 +13,6 @@ import re
import shutil
import stat
import struct
import imp
import string
import tempfile
@ -1068,7 +1067,7 @@ class build_apps(setuptools.Command):
freezer_extras.update(freezer.extras)
freezer_modules.update(freezer.getAllModuleNames())
for suffix in freezer.mf.suffixes:
if suffix[2] == imp.C_EXTENSION:
if suffix[2] == 3: # imp.C_EXTENSION:
ext_suffixes.add(suffix[0])
for appname, scriptname in self.gui_apps.items():

View File

@ -241,6 +241,18 @@ INLINE PyObject *PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObje
}
#endif
/* Python 3.12 */
#if PY_VERSION_HEX < 0x030C0000
# define PyLong_IsNonNegative(value) (Py_SIZE((value)) >= 0)
#else
INLINE bool PyLong_IsNonNegative(PyObject *value) {
int overflow = 0;
long longval = PyLong_AsLongAndOverflow(value, &overflow);
return overflow == 1 || longval >= 0;
}
#endif
/* Other Python implementations */
#endif // HAVE_PYTHON

View File

@ -12,9 +12,7 @@ import os
import sys
from optparse import OptionParser
from makepandacore import *
# DO NOT CHANGE TO sysconfig - see GitHub issue #1230
from distutils.sysconfig import get_python_lib
from locations import get_python_lib
MIME_INFO = (

32
makepanda/locations.py Normal file
View File

@ -0,0 +1,32 @@
__all__ = [
'get_python_inc',
'get_config_var',
'get_python_version',
'PREFIX',
'get_python_lib',
'get_config_vars',
]
import sys
if sys.version_info < (3, 12):
from distutils.sysconfig import *
else:
from sysconfig import *
PREFIX = get_config_var('prefix')
def get_python_inc(plat_specific=False):
path_name = 'platinclude' if plat_specific else 'include'
return get_path(path_name)
def get_python_lib(plat_specific=False, standard_lib=False):
if standard_lib:
path_name = 'stdlib'
if plat_specific:
path_name = 'plat' + path_name
elif plat_specific:
path_name = 'platlib'
else:
path_name = 'purelib'
return get_path(path_name)

View File

@ -942,8 +942,7 @@ def MakeInstallerAndroid(version, **kwargs):
shutil.copy(os.path.join(source_dir, base), target)
# Copy the Python standard library to the .apk as well.
# DO NOT CHANGE TO sysconfig - see #1230
from distutils.sysconfig import get_python_lib
from locations import get_python_lib
stdlib_source = get_python_lib(False, True)
stdlib_target = os.path.join("apkroot", "lib", "python{0}.{1}".format(*sys.version_info))
copy_python_tree(stdlib_source, stdlib_target)

View File

@ -30,12 +30,10 @@ except:
print("Please install the development package of Python and try again.")
exit(1)
if sys.version_info >= (3, 10):
from sysconfig import get_platform
else:
from distutils.util import get_platform
from makepandacore import *
from sysconfig import get_platform
try:
import zlib
except:

View File

@ -21,6 +21,7 @@ import sys
import threading
import _thread as thread
import time
import locations
SUFFIX_INC = [".cxx",".cpp",".c",".h",".I",".yxx",".lxx",".mm",".rc",".r"]
SUFFIX_DLL = [".dll",".dlo",".dle",".dli",".dlm",".mll",".exe",".pyd",".ocx"]
@ -2195,7 +2196,7 @@ def SdkLocatePython(prefer_thirdparty_python=False):
# On macOS, search for the Python framework directory matching the
# version number of our current Python version.
sysroot = SDK.get("MACOSX", "")
version = sysconfig.get_python_version()
version = locations.get_python_version()
py_fwx = "{0}/System/Library/Frameworks/Python.framework/Versions/{1}".format(sysroot, version)
@ -2220,19 +2221,19 @@ def SdkLocatePython(prefer_thirdparty_python=False):
LibDirectory("PYTHON", py_fwx + "/lib")
#elif GetTarget() == 'windows':
# SDK["PYTHON"] = os.path.dirname(sysconfig.get_python_inc())
# SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version()
# SDK["PYTHON"] = os.path.dirname(locations.get_python_inc())
# SDK["PYTHONVERSION"] = "python" + locations.get_python_version()
# SDK["PYTHONEXEC"] = sys.executable
else:
SDK["PYTHON"] = sysconfig.get_python_inc()
SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version() + abiflags
SDK["PYTHON"] = locations.get_python_inc()
SDK["PYTHONVERSION"] = "python" + locations.get_python_version() + abiflags
SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
if CrossCompiling():
# We need a version of Python we can run.
SDK["PYTHONEXEC"] = sys.executable
host_version = "python" + sysconfig.get_python_version() + abiflags
host_version = "python" + locations.get_python_version() + abiflags
if SDK["PYTHONVERSION"] != host_version:
exit("Host Python version (%s) must be the same as target Python version (%s)!" % (host_version, SDK["PYTHONVERSION"]))
@ -3386,7 +3387,7 @@ def GetExtensionSuffix():
def GetPythonABI():
if not CrossCompiling():
soabi = sysconfig.get_config_var('SOABI')
soabi = locations.get_config_var('SOABI')
if soabi:
return soabi
@ -3507,8 +3508,8 @@ def GetCurrentPythonVersionInfo():
"soabi": GetPythonABI(),
"ext_suffix": GetExtensionSuffix(),
"executable": sys.executable,
"purelib": sysconfig.get_python_lib(False),
"platlib": sysconfig.get_python_lib(True),
"purelib": locations.get_python_lib(False),
"platlib": locations.get_python_lib(True),
}

View File

@ -11,10 +11,11 @@ import tempfile
import subprocess
import time
import struct
from sysconfig import get_platform, get_config_var
from optparse import OptionParser
from base64 import urlsafe_b64encode
from makepandacore import LocateBinary, GetExtensionSuffix, SetVerbose, GetVerbose, GetMetadataValue, CrossCompiling, GetThirdpartyDir, SDK, GetStrip
from locations import get_config_var
from sysconfig import get_platform
def get_abi_tag():

View File

@ -92,19 +92,7 @@ BMPlenrgbtable(int classv, unsigned long bitcount)
pm_error(er_internal, "BMPlenrgbtable");
return 0;
}
switch (classv)
{
case C_WIN:
lenrgb = 4;
break;
case C_OS2:
lenrgb = 3;
break;
default:
pm_error(er_internal, "BMPlenrgbtable");
return 0;
}
lenrgb = (classv == C_OS2) ? 3 : 4;
return (1 << bitcount) * lenrgb;
}

View File

@ -55,6 +55,7 @@ public:
unsigned long offBits;
unsigned short cBitCount;
unsigned short cCompression;
int indexed;
int classv;

View File

@ -177,6 +177,7 @@ BMPreadinfoheader(
unsigned long *pcx,
unsigned long *pcy,
unsigned short *pcBitCount,
unsigned short *pcCompression,
int *pclassv)
{
unsigned long cbFix;
@ -185,6 +186,7 @@ BMPreadinfoheader(
unsigned long cx = 0;
unsigned long cy = 0;
unsigned short cBitCount = 0;
unsigned long cCompression = 0;
int classv = 0;
cbFix = GetLong(fp);
@ -229,7 +231,9 @@ BMPreadinfoheader(
* for the required total.
*/
if (classv != C_OS2) {
for (int i = 0; i < (int)cbFix - 16; i += 4) {
cCompression = GetLong(fp);
for (int i = 0; i < (int)cbFix - 20; i += 4) {
GetLong(fp);
}
}
@ -273,11 +277,13 @@ BMPreadinfoheader(
pm_message("cy: %d", cy);
pm_message("cPlanes: %d", cPlanes);
pm_message("cBitCount: %d", cBitCount);
pm_message("cCompression: %d", cCompression);
#endif
*pcx = cx;
*pcy = cy;
*pcBitCount = cBitCount;
*pcCompression = cCompression;
*pclassv = classv;
*ppos += cbFix;
@ -401,7 +407,7 @@ BMPreadbits(xel *array, xelval *alpha_array,
unsigned long cx,
unsigned long cy,
unsigned short cBitCount,
int /* classv */,
unsigned long cCompression,
int indexed,
pixval *R,
pixval *G,
@ -411,35 +417,74 @@ BMPreadbits(xel *array, xelval *alpha_array,
readto(fp, ppos, offBits);
if(cBitCount > 24 && cBitCount != 32)
{
pm_error("%s: cannot handle cBitCount: %d"
,ifname
,cBitCount);
if (cBitCount > 24 && cBitCount != 32) {
pm_error("%s: cannot handle cBitCount: %d", ifname, cBitCount);
}
/*
* The picture is stored bottom line first, top line last
*/
if (cCompression == 1) {
// RLE8 compression
xel *row = array + (cy - 1) * cx;
xel *p = row;
unsigned long nbyte = 0;
while (true) {
int first = GetByte(fp);
int second = GetByte(fp);
nbyte += 2;
for (y = (long)cy - 1; y >= 0; y--)
{
int rc;
rc = BMPreadrow(fp, ppos, array + y*cx, alpha_array + y*cx, cx, cBitCount, indexed, R, G, B);
if(rc == -1)
{
pm_error("%s: couldn't read row %d"
,ifname
,y);
}
if(rc%4)
{
pm_error("%s: row had bad number of bytes: %d"
,ifname
,rc);
if (first != 0) {
// Repeated index.
for (int i = 0; i < first; ++i) {
PPM_ASSIGN(*p, R[second], G[second], B[second]);
++p;
}
}
else if (second == 0) {
// End of line.
row -= cx;
p = row;
}
else if (second == 1) {
// End of image.
break;
}
else if (second == 2) {
// Delta.
int xoffset = GetByte(fp);
int yoffset = GetByte(fp);
nbyte += 2;
row -= cx * yoffset;
p += xoffset - cx * yoffset;
}
else {
// Absolute run.
for (int i = 0; i < second; ++i) {
int v = GetByte(fp);
++nbyte;
PPM_ASSIGN(*p, R[v], G[v], B[v]);
++p;
}
nbyte += second;
if (second % 2) {
// Pad to 16-bit boundary.
GetByte(fp);
++nbyte;
}
}
}
*ppos += nbyte;
}
else {
// The picture is stored bottom line first, top line last
for (y = (long)cy - 1; y >= 0; y--) {
int rc = BMPreadrow(fp, ppos, array + y*cx, alpha_array + y*cx, cx, cBitCount, indexed, R, G, B);
if (rc == -1) {
pm_error("%s: couldn't read row %d", ifname, y);
}
if (rc % 4) {
pm_error("%s: row had bad number of bytes: %d", ifname, rc);
}
}
}
}
/**
@ -474,7 +519,7 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
pos = 0;
BMPreadfileheader(file, &pos, &offBits);
BMPreadinfoheader(file, &pos, &cx, &cy, &cBitCount, &classv);
BMPreadinfoheader(file, &pos, &cx, &cy, &cBitCount, &cCompression, &classv);
if (offBits != BMPoffbits(classv, cBitCount)) {
pnmimage_bmp_cat.warning()
@ -523,9 +568,10 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
int PNMFileTypeBMP::Reader::
read_data(xel *array, xelval *alpha_array) {
BMPreadbits(array, alpha_array, _file, &pos, offBits, _x_size, _y_size,
cBitCount, classv, indexed, R, G, B);
cBitCount, cCompression, indexed, R, G, B);
if (pos != BMPlenfile(classv, cBitCount, _x_size, _y_size)) {
if (cCompression != 1 &&
pos != BMPlenfile(classv, cBitCount, _x_size, _y_size)) {
pnmimage_bmp_cat.warning()
<< "Read " << pos << " bytes, expected to read "
<< BMPlenfile(classv, cBitCount, _x_size, _y_size) << " bytes\n";

View File

@ -20,7 +20,7 @@
*/
void Extension<BitArray>::
__init__(PyObject *init_value) {
if (!PyLong_Check(init_value) || Py_SIZE(init_value) < 0) {
if (!PyLong_Check(init_value) || !PyLong_IsNonNegative(init_value)) {
PyErr_SetString(PyExc_ValueError, "BitArray constructor requires a positive integer");
return;
}
@ -76,7 +76,7 @@ __getstate__() const {
*/
void Extension<BitArray>::
__setstate__(PyObject *state) {
if (Py_SIZE(state) >= 0) {
if (PyLong_IsNonNegative(state)) {
__init__(state);
} else {
PyObject *inverted = PyNumber_Invert(state);

View File

@ -17,7 +17,7 @@
template<class BMType>
INLINE void Extension<DoubleBitMask<BMType> >::
__init__(PyObject *init_value) {
if (!PyLong_Check(init_value) || Py_SIZE(init_value) < 0) {
if (!PyLong_Check(init_value) || !PyLong_IsNonNegative(init_value)) {
PyErr_SetString(PyExc_ValueError, "DoubleBitMask constructor requires a positive integer");
return;
}

View File

@ -1,4 +1,6 @@
import os
import platform
import pytest
from panda3d import core
@ -16,12 +18,14 @@ def run_cg_compile_check(gsg, shader_path, expect_fail=False):
assert shader is not None
@pytest.mark.skipif(platform.machine().lower() == 'arm64', reason="Cg not supported on arm64")
def test_cg_compile_error(gsg):
"""Test getting compile errors from bad Cg shaders"""
shader_path = core.Filename(SHADERS_DIR, 'cg_bad.sha')
run_cg_compile_check(gsg, shader_path, expect_fail=True)
@pytest.mark.skipif(platform.machine().lower() == 'arm64', reason="Cg not supported on arm64")
def test_cg_from_file(gsg):
"""Test compiling Cg shaders from files"""
shader_path = core.Filename(SHADERS_DIR, 'cg_simple.sha')

58
tests/dist/test_FreezeTool.py vendored Normal file
View File

@ -0,0 +1,58 @@
from direct.dist.FreezeTool import Freezer, PandaModuleFinder
import sys
def test_Freezer_moduleSuffixes():
freezer = Freezer()
for suffix, mode, type in freezer.mf.suffixes:
if type == 2: # imp.PY_SOURCE
assert mode == 'rb'
def test_Freezer_getModulePath_getModuleStar(tmp_path):
# Package 1 can be imported
package1 = tmp_path / "package1"
package1.mkdir()
(package1 / "submodule1.py").write_text("")
(package1 / "__init__.py").write_text("")
# Package 2 can not be imported
package2 = tmp_path / "package2"
package2.mkdir()
(package2 / "submodule2.py").write_text("")
(package2 / "__init__.py").write_text("raise ImportError\n")
# Module 1 can be imported
(tmp_path / "module1.py").write_text("")
# Module 2 can not be imported
(tmp_path / "module2.py").write_text("raise ImportError\n")
backup = sys.path
try:
# Don't fail if first item on path does not exist
sys.path = [str(tmp_path / "nonexistent"), str(tmp_path)]
freezer = Freezer()
assert freezer.getModulePath("nonexist") == None
assert freezer.getModulePath("package1") == [str(package1)]
assert freezer.getModulePath("package2") == [str(package2)]
assert freezer.getModulePath("package1.submodule1") == None
assert freezer.getModulePath("package1.nonexist") == None
assert freezer.getModulePath("package2.submodule2") == None
assert freezer.getModulePath("package2.nonexist") == None
assert freezer.getModulePath("module1") == None
assert freezer.getModulePath("module2") == None
assert freezer.getModuleStar("nonexist") == None
assert freezer.getModuleStar("package1") == ['submodule1']
assert freezer.getModuleStar("package2") == ['submodule2']
assert freezer.getModuleStar("package1.submodule1") == None
assert freezer.getModuleStar("package1.nonexist") == None
assert freezer.getModuleStar("package2.submodule2") == None
assert freezer.getModuleStar("package2.nonexist") == None
assert freezer.getModuleStar("module1") == None
assert freezer.getModuleStar("module2") == None
finally:
sys.path = backup

View File

@ -118,6 +118,9 @@ def test_bitarray_pickle():
ba = BitArray(123)
assert ba == pickle.loads(pickle.dumps(ba, -1))
ba = BitArray(1 << 128)
assert ba == pickle.loads(pickle.dumps(ba, -1))
ba = BitArray(94187049178237918273981729127381723)
assert ba == pickle.loads(pickle.dumps(ba, -1))

View File

@ -2,6 +2,7 @@
# missing imports. It is useful for a quick and dirty test to make sure
# that there are no obvious build issues.
import pytest
import sys
# This will print out imports on the command line.
#import direct.showbase.VerboseImport
@ -9,7 +10,7 @@ import pytest
def test_imports_panda3d():
import importlib, os, sys
import importlib, os
import panda3d
# Look for panda3d.* modules in builtins - pfreeze might put them there.
@ -165,6 +166,7 @@ def test_imports_direct():
import direct.showbase.TaskThreaded
import direct.showbase.ThreeUpShow
import direct.showbase.Transitions
if sys.version_info < (3, 12):
import direct.showbase.VFSImporter
import direct.showbase.WxGlobal
import direct.showutil.BuildGeometry