未指定测试路径时Pytest抛出TypeError错误问题排查
问题描述
我的tests/目录下有conftest.py文件,内容如下:
import pytest from pyspark import SparkConf from sedona.utils import SedonaKryoRegistrator, KryoSerializer from sedona.register import SedonaRegistrator from pyspark.sql import SparkSession @pytest.fixture def spark_session_sedona(): parameters = {'spark.driver.maxResultSize': '3g', 'spark.hadoop.fs.s3a.impl': 'org.apache.hadoop.fs.s3a.S3AFileSystem', 'spark.sql.execution.arrow.pyspark.enabled': True, 'spark.scheduler.mode': 'FAIR'} spark_conf = SparkConf().setAll(parameters.items()) spark_session_conf = ( SparkSession.builder.appName('appName') .enableHiveSupport() .config('spark.jars.packages', 'org.apache.hadoop:hadoop-common:3.3.4,' 'org.apache.hadoop:hadoop-azure:3.3.4,' 'com.microsoft.azure:azure-storage:8.6.6,' 'io.delta:delta-core_2.12:1.0.0,' 'org.apache.sedona:sedona-python-adapter-3.0_2.12:1.2.1-incubating,' 'org.datasyslab:geotools-wrapper:1.3.0-27.2') .config(conf=spark_conf) .config("spark.serializer", KryoSerializer.getName) .config("spark.kryo.registrator", SedonaKryoRegistrator.getName) ) return spark_session_conf.getOrCreate()
测试用例依赖该fixture,执行代码:
SedonaRegistrator.registerAll(spark)
执行pytest命令时,报错:
TypeError: 'JavaPackage' object is not callable
但执行pytest src/tests/test_sedona.py时测试正常通过。完整错误信息:
src/tests/utils/test_lanes_scale.py:39: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ src/adas_lanes/utils/lanes_scale.py:112: in lanes_sql_line SedonaRegistrator.registerAll(spark) /home/vscode/.local/lib/python3.8/site-packages/sedona/register/geo_registrator.py:43: in registerAll cls.register(spark) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ cls = <class 'sedona.register.geo_registrator.SedonaRegistrator'> spark = <pyspark.sql.session.SparkSession object at 0x7f847a72f340> @classmethod def register(cls, spark: SparkSession): > return spark._jvm.SedonaSQLRegistrator.registerAll(spark._jsparkSession) E TypeError: 'JavaPackage' object is not callable
原因分析
核心问题是Spark Session复用导致的依赖缺失:
- 执行
pytest时会遍历所有测试文件,若某个测试先启动了不带Sedona依赖的Spark Session(比如其他fixture或测试代码自行创建的实例),后续测试会复用这个已存在的Session。由于该Session未加载Sedona的JAR包,调用SedonaRegistrator.registerAll时就会出现JavaPackage无法调用的错误。 - 而执行
pytest src/tests/test_sedona.py时,仅运行指定文件,此时Spark Session通过spark_session_sedonafixture创建,已加载所有Sedona相关依赖,因此能正常注册函数。
解决办法
- 统一测试的Spark Session依赖:检查项目中其他测试代码,将所有自行创建Spark Session的逻辑替换为依赖
spark_session_sedonafixture,确保所有测试使用的Session都包含Sedona依赖。 - 强制创建新Session避免复用:修改
spark_session_sedonafixture,在创建新Session前关闭已存在的实例,并在测试结束后清理Session:
@pytest.fixture def spark_session_sedona(): # 关闭已存在的Spark Session,避免复用 existing_spark = SparkSession.builder.getOrCreate() existing_spark.stop() parameters = {'spark.driver.maxResultSize': '3g', 'spark.hadoop.fs.s3a.impl': 'org.apache.hadoop.fs.s3a.S3AFileSystem', 'spark.sql.execution.arrow.pyspark.enabled': True, 'spark.scheduler.mode': 'FAIR'} spark_conf = SparkConf().setAll(parameters.items()) spark_session_conf = ( SparkSession.builder.appName('appName') .enableHiveSupport() .config('spark.jars.packages', 'org.apache.hadoop:hadoop-common:3.3.4,' 'org.apache.hadoop:hadoop-azure:3.3.4,' 'com.microsoft.azure:azure-storage:8.6.6,' 'io.delta:delta-core_2.12:1.0.0,' 'org.apache.sedona:sedona-python-adapter-3.0_2.12:1.2.1-incubating,' 'org.datasyslab:geotools-wrapper:1.3.0-27.2') .config(conf=spark_conf) .config("spark.serializer", KryoSerializer.getName) .config("spark.kryo.registrator", SedonaKryoRegistrator.getName) ) spark = spark_session_conf.getOrCreate() yield spark # 测试结束后关闭Session spark.stop()
- 控制测试执行顺序:若无法统一fixture,可通过
pytest-ordering插件指定测试执行顺序,让依赖Sedona的测试优先运行,确保初始化正确的Session。
内容的提问来源于stack exchange,提问作者Rorepio
相关产品推荐
相关产品推荐

