You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未指定测试路径时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_sedona fixture创建,已加载所有Sedona相关依赖,因此能正常注册函数。
解决办法
  1. 统一测试的Spark Session依赖:检查项目中其他测试代码,将所有自行创建Spark Session的逻辑替换为依赖spark_session_sedona fixture,确保所有测试使用的Session都包含Sedona依赖。
  2. 强制创建新Session避免复用:修改spark_session_sedona fixture,在创建新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()
  1. 控制测试执行顺序:若无法统一fixture,可通过pytest-ordering插件指定测试执行顺序,让依赖Sedona的测试优先运行,确保初始化正确的Session。

内容的提问来源于stack exchange,提问作者Rorepio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:40:21