I still don't understand what you're talking about.
> If your import stripped your access to an attribute
Python doesn't have class access modifiers, and in particular import does not strip access to attributes in Python. There are two ways Python modifies behaviour in the presence of leading underscores:
1. If there is a module attribute (i.e. a variable in a module) starting with an underscore, it will not be imported when doing `import * from some_module` -- which is not recommended anyway. Importing `some_module` directly will give normal access to the attribute, as `some_module._foo`.
2. If a class or instance attribute's name begins with a double underscore, it will not be accessible directly; however its name is simply mungled at compile time:
> class Foo:
> __foobar = "__foobar"
>
> def __init__(self):
> self.__bar = "__bar"
> self.__baz__ = "__baz__"
>
> Foo.__foobar
AttributeError: 'Foo' object has no attribute '__foobar'
> foo = Foo()
> foo.__bar
AttributeError: 'Foo' object has no attribute '__bar'
> Foo._Foo__foobar
'__foobar'
> foo._Foo__bar
'__bar'
> # Note that does not hold for attributes both starting and ending in double underscores
> # (so-called 'dunder' attributes):
foo.__baz__
'__baz__'
You are correct that underscores are a convention, but in Python one simply cannot count on the kind of access control that exists in other languages, especially when writing code that is supposed to be executed in unknown contexts (i.e. a library). When writing tests, one presumably has full control over both the code and the execution context, so this kinds of tricks can be used relatively safely; that being said, test runners like pytest tend to provide their own abstractions and tools around those tricks anyway.
_single_leading_underscore: weak “internal use” indicator. E.g. from M import * does not import objects whose names start with an underscore. - https://peps.python.org/pep-0008/
Your first point is something I mentioned in my comment (although admittedly I mixed the order of the command). In general it's a bad idea to import everything from a module into the global namespace; it's recommended to keep it under some namespace for context:
I.e., assuming my_module has function foo, instead of: