pythonpython-behave

behave cannot find class


I am new to Python, and am trying behave for the first time. If it matters, I am using VSCode as my editor, and run behave from the VSCode terminal.

My project is setup like this:

payz
  features
    tuples.feature
    steps
      toople.py
  toople.py

toople.py contains:

from dataclasses import dataclass


@dataclass
class Toople:
    x: float = 0
    y: float = 0
    z: float = 0
    w: float = 0

    def is_point(self) -> bool:
        return self.w == 1.0

    def is_vector(self) -> bool:
        return self.w == 0.0

The feature contains:


Feature: Tuples, Vectors, and Points

  Scenario: A tuple with w=1.0 is a point
    Given a ← tuple(4.3, -4.2, 3.1, 1.0)
    Then a.x = 4.3
    And a.y = -4.2
    And a.z = 3.1
    And a.w = 1.0
    And a is a point
    And a is not a vector

The feature steps has this defined:

from behave import *
from toople import *


@given('a ← tuple(4.3, -4.2, 3.1, 1.0)')
def step_impl(context):
    context.a = Toople(x=4.3, y=-4.2, z=3.1, w=1.0)

running behave from the CLI fails with this error:

          context.a = Toople(x=4.3, y=-4.2, z=3.1, w=1.0)
                      ^^^^^^
      NameError: name 'Toople' is not defined

from the python shell, it works fine:

 ~/src/payz | on main !2 ?2  python                                                                                                                                            1 err | at 07:39:15 PM 
Python 3.11.0 (main, Oct 25 2022, 18:01:25) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from toople import *
>>> a = Toople(x=4.3,y=2.2,z=3.3,w=1.0)
>>> print(a)
Toople(x=4.3, y=2.2, z=3.3, w=1.0)
>>> print(a.is_point())
True
>>> print(a.is_vector())
False
>>> 

Toople is on purpose to avoid any clases with the builtin Tuple.

I have PYTHONDONTWRITEBYTECODE=1 in my environment, in an attempt to rule out any caching (__pycache__) issues.

I have changed the class file and saved it in between trying behave, and don't see any behavior change.

I had these tests at least partially passing, and then decided to try to rename the class to Tuple. That failed, so I tried undoing that change, which is when I started experiencing this failure. I have seen the Given pass before, so, I'm not seeing what I broke.

How do I debug this? ...and/or...fix this so the feature passes?


Solution

  • The problem is that you are naming two different files with the same name, and that produces this error.

    Try to rename the dataclass file to toople_dataclass.py and in your steps file write this:

    from behave import *
    
    from toople_dataclass import Toople
    
    
    @given('a ← tuple(4.3, -4.2, 3.1, 1.0)')
    def step_impl(context):
        context.a = Toople(x=4.3, y=-4.2, z=3.1, w=1.0)
    

    That way works for me.