I have a src
directory containing a helpers
directory. Inside of the modules inside of the helpers
directory,
I use
import os
import sys
sys.path.append(os.path.dirname(__file__))
to make relative imports work.
I have a command
dataclass in one of the helpers, but there seem to be two types depending from where it's called.
I have a function like this:
@dataclass
class Command:
name: str
description: str
# ...
class CommandClass():
commands: list[Command] = []
def attach_command(self, command: Command) -> None:
self.commands.append(command)
But somehow the type for a manually constructed Command
inside of attach_command
is not the same as the one of the command
argument.
# ...
assert type(command) == type(Command("my_name", "my_description")) # false
# type(command): <class 'command.Command'>
# type(Command("my_name", "my_description")): <class 'helpers.command.Command'>
I was expecting both to at least be evaluated to be the same.
Minimal reproducible example
A minimal reproducible example can be found here. It's not small, but it shows my issue. It also made me realize, that I should have added more information above.
It looks like a Path problem. As you change
sys.path
to allow relative imports, you managed to load 2 instances of thecommand
module, one with a path (relative to the currentsys.path
at the time of loading) beinghelpers.command
, the latter with a path beingcommand
.That is the reason why relative imports are normally restricted inside packages, and why a package is a module having a
__path__
attribute. The goal of that machinery is to make sure that a module should never have 2 distinct paths.Workaround:
A simple workaround would be to always include a module from the same path. In your example, it is enough to change
import command
withfrom helpers import command
in plugin.py:But IMHO the real solution would be to stop playing with
sys.path
and properly convertsrc
to a neat and clean package.