模块名称重载和导入路径

时间:2012-01-06 17:28:10

标签: module import twisted testcase trial

下面的代码失败,因为twisted.trial.unittest.TestCase,即所需的基类,不是基类。

from twisted.trial import unittest
from unittest import TestCase
import myapp

class Feature(TestCase):

  def setUp(self):
    self.callbackCounter = 0

  def checkCbCalled(self, expected):
      self.assertEqual(self.callbackCounter, expected)

  def testTrialCallsDeferred(self):

      d = myapp.buildFeature()
      self.addCleanup(self.checkCbCalled, expected=1)
      def cb(res):
        self.callbackCounter += 1
      d.addCallback(cb).addErrback(self.fail)
      return d           # does not fire because of 'import rules'?

如果我说过

from twisted.trial import unittest as trialut
from trialut import TestCase 

或者,更好:

from twisted.trial.unittest import TestCase

然后测试将按预期运行并且trial.unittest.TestCase会解雇我的延迟。

这似乎是本地最近导入的东西应该取代{lib / pythonX.X / unittest}中可用的东西。我知道它必须是基于sys.path或其他隐式或显式的规则。这让我有点太长时间了,因为我没有调用addCleanup并且所有测试都在通过,因为返回的延迟实例没有被触发。

我打破了一些规则,请告知一些阅读或其他。

由于 麦克

1 个答案:

答案 0 :(得分:2)

目前还不清楚你期望它如何工作,但听起来你至少对Python中的模块行为有些困惑。

import语句(有时)从源文件加载模块,然后将本地作用域中的名称绑定到该模块对象。

所以,当你这样做时:

from twisted.trial import unittest

您正在加载twisted.trial.unittest模块,然后绑定本地名称unittest

这与以下陈述没有任何有趣的交互:

from unittest import TestCase

加载unittest模块,然后将本地名称TestCase绑定到该模块的TestCase属性引用的对象。

当您稍后继承TestCase时:

class Feature(TestCase):
    ...

您在本地范围内直接使用名称TestCase - 一个引用TestCase模块定义的unittest类的名称。请注意,它与Twisted的twisted.trial.unittest模块没有任何关系,即使您已经加载了该模块。您必须使用其中一个属性才能使用其功能。

改进代码行为的一个变化就是完全停止使用标准库unittest模块。删除这一行:

from unittest import TestCase

用以下代码替换您的类定义:

class Feature(unittest.TestCase):

不要对标准库unittest模块共享Twisted twisted.trial.unittest模块名称的一部分这一事实感到困惑。它们是具有不同(虽然相似,有时重叠)特征的不同模块。上面示例中的类定义使用twisted.trial.unittest,因为它位于原始行之后:

from twisted.trial import unittest

实际使用Twisted的TestCase(来自twisted.trial.unittest)而非标准库的TestCase(来自unittest)后,您将获得所期望的行为测试方法返回Deferred。这是因为它是Twisted提供此功能,而不是标准库。