On 20 March 2018 at 07:23, Chris Billington <chrisjbilling...@gmail.com>
wrote:

> It seems like running from within a package directory is bad news mostly
> *because* of the double import problem, [...]
>

I think the main issue regarding loading a module from within a package
directory is about the paths, non-absolute non-relative import names, and
[mainly] a desire to keep a module+script behavior in a single-file, not
really about double importing.

If you have a package "a" with a subpackage "b" that has a module "c", its
file "a/b/c.py" would be:

- Externally/internally imported as "from a.b import c"
- Internally imported as "from .b import c", for modules in the "a" package
level
- Internally imported as "from . import c", for modules in the "b"
subpackage level
- Internally imported as "from ..b import c", for modules in a subpackage
level sibling to "b"

IMHO, both internally and externally to the package, you should never do
"from b import c".

The 3 issues I see:

1. [sys.path trick] Doing "from b import c" from within "a" wouldn't load
the "a/b/c.py" file unless you do some nonstandard sys.path trick to search
for modules/packages in both the root directory (to import "a") and the "a"
package-level directory (to import "b"). This scenario makes both "a.b" and
"b" imports available, distinct import names to the same file.

2. [non-absolute non-relative name] Using "from b import c" would be the
way to [externally] load this module from the "a" package-level directory
as the current working directory if the root directory isn't in the
sys.path. But, in such a scenario, the "from a.b import c" simply don't
work. That's the misleading point: you can import some package internals
with alternative names, while the package itself can't be imported. The
current working directory or a patched sys.path is the "culprit" that
enforces a distinct/specific naming for the imports, which are otherwise
invalid. It's not relative (there's no leading dot), but I'd not say it's
absolute (as there's no leading "a." where "a" is a package), it's perhaps
a relative-importable-from-external-scripts naming style (or
absolute-from-internals), though it has the "absolute import" syntax.

3. [module+script in a single internal file] One might wish to load a
module as a script, using a `if __name__ == "__main__":` block to segregate
the twofold behavior: one as a module, another as a script. That's fine
when dealing with a file that doesn't belong to a package. But, inside a
package structure, loading a single internal module as a script breaks the
paths (and the import names). To avoid that, I [almost] always use relative
imports, so the file can't be loaded as a script, and I write the script in
another file, either in the root directory (level that has the package
directory) or as a "package_name/__main__.py" file, importing the stuff it
needs from any module using the same names one would use otherwere. That
is, the solution is to split the file in two (an internal module file, and
an external script file).

Nevertheless, if the same file can be imported from two valid
paths/addresses, should them be a single module? I mean, should "file" and
"module" be 1-to-1 concepts, or should "address/name" and "module" be
1-to-1 concepts (or neither)? How about symbolic links? I'm not sure, but
linking "absolute file name" to "module" sounds like endorsing the
relative-importable-from-external-scripts naming style, and IMHO that's not
the main issue. As packages with modules that internally imports themselves
has to choose between relative and absolute import names, I don't see [2]
as a real issue.

-- 
Danilo J. S. Bellini
---------------
"*It is not our business to set up prohibitions, but to arrive at
conventions.*" (R. Carnap)
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to