On Thu, Dec 10, 2020 at 11:10:05PM +0200, Serhiy Storchaka wrote:

> > There are other ways you can get this same effect. Should we have 
> > warnings for them all?
> > 
> >     import spam
> >     ImportWarning: spam.py is a hard link to eggs.py and we
> >     want to force you to read the docs to learn why this is
> >     a bad idea.
> 
> Do you know how to determine the name of the target of a hard link?

I know how to do it in the Linux shell: get the inode number of the 
file, then search the file system for files with that inode number. Or 
you can use the `-samefile` option to `find`.

In the case of Python modules, you wouldn't need to search the entire 
file system, but only those parts in the PYTHONPATH.

Of course this would be expensive, but it would also be unnecessary. 
This is not the sort of thing the intepreter should treat as a bug or 
even as a warning. It is too rare, too costly to check, and if users are 
doing it, they probably want the current behaviour.

Python is a Consenting Adults language, and I hope it remains as such. 
There are certain things which consenting adults should be allowed to do 
without it raising an error, and one of those is creating two 
independent module objects from a hard linked file.


> > I don't think we should scold users with warnings and errors, breaking 
> > their code, because it *might* be bad, or because the code looks weird. 
> > Weird code is not illegal.
> 
> Agree, but in many cases the code is written in a weird way because the
> author did not know about the right way. We do not scold users, we
> inform them and help to fix potential error.

Anything could be a potential error. We should require something a 
little stronger than just "potential error" before breaking backwards 
compatibility.

Unless there is strong evidence of real errors, we normally leave 
enforcement of style issues to linters, coding standards and user 
education. For example, we are deprecating `bool(NotImplemented)` 
because we have strong evidence of lots of buggy code from operator 
dunders not treating NotImplemented correctly.

That's all I am asking for here: if there is strong evidence of actual, 
real world bugs caused by this, then we should consider a change in 
behaviour. Without that evidence, then "backwards compatibility" and 
"consenting adults" should take precedence.

Otherwise, we are breaking code that works well enough to satisfy the 
code's owner, even if it isn't perfect, even if it doesn't meet best 
practice.


[...]
> >> I am not even sure that it works.
> > 
> > Seems to work fine when I tried it:
> > 
> >     $ cat package/__init__.py 
> >     print("importing toplevel package __init__.py")
> >     $ cat package/__init__/__init__.py
> >     print("importing subpackage __init__/__init__.py")
> > 
> > 
> > And importing them:
> > 
> >     >>> import package.__init__
> >     importing toplevel package __init__.py
> >     importing subpackage __init__/__init__.py
> > 
> > 
> > If it didn't work, I would call that a bug. "__init__.py" module files 
> > are special; *directories* called "__init__" are not special, they're 
> > just an ordinary name.
> 
> Now remove package/__init__/__init__.py, add package/__init__/module.py
> and try to import it.

Now *that* looks like a bug to me. Here is my package setup:


    package /
    +-- __init__.py
    +-- directory /
    |   +-- module.py
    |   +-- __init__ /
    |       +-- module.py
    +-- __init__ /
        +-- module.py


Importing package.__init__.module fails, but importing 
package.directory.__init__.module succeeds even though neither init 
directory contains an __init__.py file.


```
[steve ~]$ python3 -c "import package.directory.module"
importing toplevel package __init__.py
importing package.directory.module

[steve ~]$ python3 -c "import package.directory.__init__.module"
importing toplevel package __init__.py
importing package.directory.__init__.module

[steve ~]$ python3 -c "import package.__init__.module"
importing toplevel package __init__.py
importing toplevel package __init__.py
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'package.__init__.module'; 
'package.__init__' is not a package

```

Can somebody convince me that this is working correctly? Otherwise it 
looks like a bug to me.


-- 
Steve
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/LB3FOWJOYNRT3EYYVIIH7RNUKJQC3QUG/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to