Я хотел бы создать класс, который имеет abc.ABCMeta
как метакласс и совместим как с Python 2.7, так и с Python 3.5. До сих пор мне удалось это сделать либо на 2.7, либо на 3.5 - но никогда в обеих версиях одновременно. Может ли кто-нибудь дать мне руку?
Python 2.7:
import abc
class SomeAbstractClass(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def do_something(self):
pass
Python 3.5:
import abc
class SomeAbstractClass(metaclass=abc.ABCMeta):
@abc.abstractmethod
def do_something(self):
pass
Тестирование
Если мы проведем следующий тест с использованием подходящей версии интерпретатора Python (Python 2.7 → Example 1, Python 3.5 → Example 2), он успешно выполнит оба сценария:
import unittest
class SomeAbstractClassTestCase(unittest.TestCase):
def test_do_something_raises_exception(self):
with self.assertRaises(TypeError) as error:
processor = SomeAbstractClass()
msg = str(error.exception)
expected_msg = "Can't instantiate abstract class SomeAbstractClass with abstract methods do_something"
self.assertEqual(msg, expected_msg)
Проблема
При запуске теста с использованием Python 3.5 ожидаемого поведения не происходит (TypeError
не возникает при создании SomeAbstractClass
):
======================================================================
FAIL: test_do_something_raises_exception (__main__.SomeAbstractClassTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/tati/sample_abc.py", line 22, in test_do_something_raises_exception
processor = SomeAbstractClass()
AssertionError: TypeError not raised
----------------------------------------------------------------------
В то время как запуск теста с использованием Python 2.7 повышает значение SyntaxError
:
Python 2.7 incompatible
Raises exception:
File "/home/tati/sample_abc.py", line 24
class SomeAbstractClass(metaclass=abc.ABCMeta):
^
SyntaxError: invalid syntax