PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, August 5, 2022

[FIXED] Why are certain file names not allowed for local Python source code files?

 August 05, 2022     exception, python     No comments   

Issue

There seem to be file names that are not allowed to exist in the same directory in which I'm running my Python source code because they probably conflict with a file of the same name within a module in which I've imported.

Is there a way to still keep the names the same but avoid the exception?

This seems bizarre being how long Python has been around and is not fixed or the default install of Python doesn't avoid this, despite what modules are imported (ie: openpyxl in the copy.py scenario & smtplib in the email.py scenario).

Below are two example exceptions. My source code is in the testing.py file. And files copy.py and email.py are in the same directory as testing.py. For now, I renamed them to copy2.py and email2.py, but this seems like a bad workaround.

copy.py

Traceback (most recent call last):
  File "C:\Python\Python37_64\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Python\Python37_64\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python\Python37_64\lib\cProfile.py", line 185, in <module>
    main()
  File "C:\Python\Python37_64\lib\cProfile.py", line 178, in main
    runctx(code, globs, None, options.outfile, options.sort)
  File "C:\Python\Python37_64\lib\cProfile.py", line 20, in runctx
    filename, sort)
  File "C:\Python\Python37_64\lib\profile.py", line 62, in runctx
    prof.runctx(statement, globals, locals)
  File "C:\Python\Python37_64\lib\cProfile.py", line 100, in runctx
    exec(cmd, globals, locals)
  File "C:\GitLab\redcap-p01-etl\testing.py", line 7, in <module>
    import openpyxl # openpyxl 3.0.7
  File "C:\Python\venv\Python37_64\lib\site-packages\openpyxl\__init__.py", line 6, in <module>
    from openpyxl.workbook import Workbook
  File "C:\Python\venv\Python37_64\lib\site-packages\openpyxl\workbook\__init__.py", line 4, in <module>
    from .workbook import Workbook
  File "C:\Python\venv\Python37_64\lib\site-packages\openpyxl\workbook\workbook.py", line 4, in <module>
    from copy import copy
  File "C:\GitLab\p01\copy.py", line 2
    def parse_slash_copy(const char *args):
    ^
IndentationError: unexpected indent

email.py

Traceback (most recent call last):
  File "C:\Python\Python37_64\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Python\Python37_64\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python\Python37_64\lib\cProfile.py", line 185, in <module>
    main()
  File "C:\Python\Python37_64\lib\cProfile.py", line 178, in main
    runctx(code, globs, None, options.outfile, options.sort)
  File "C:\Python\Python37_64\lib\cProfile.py", line 20, in runctx
    filename, sort)
  File "C:\Python\Python37_64\lib\profile.py", line 62, in runctx
    prof.runctx(statement, globals, locals)
  File "C:\Python\Python37_64\lib\cProfile.py", line 100, in runctx
    exec(cmd, globals, locals)
  File "C:\GitLab\p01\testing.py", line 13, in <module>
    import requests
  File "C:\Python\venv\Python37_64\lib\site-packages\requests\__init__.py", line 43, in <module>
    import urllib3
  File "C:\Python\venv\Python37_64\lib\site-packages\urllib3\__init__.py", line 11, in <module>
    from . import exceptions
  File "C:\Python\venv\Python37_64\lib\site-packages\urllib3\exceptions.py", line 3, in <module>
    from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead
  File "C:\Python\venv\Python37_64\lib\site-packages\urllib3\packages\six.py", line 199, in load_module
    mod = mod._resolve()
  File "C:\Python\venv\Python37_64\lib\site-packages\urllib3\packages\six.py", line 113, in _resolve
    return _import_module(self.mod)
  File "C:\Python\venv\Python37_64\lib\site-packages\urllib3\packages\six.py", line 82, in _import_module
    __import__(name)
  File "C:\Python\Python37_64\lib\http\client.py", line 71, in <module>
    import email.parser
  File "C:\GitLab\p01\email.py", line 1, in <module>
    import smtplib
  File "C:\Python\Python37_64\lib\smtplib.py", line 47, in <module>
    import email.utils
ModuleNotFoundError: No module named 'email.utils'; 'email' is not a package

Solution

This seems bizarre being how long Python has been around and is not fixed or the default install of Python doesn't avoid this, despite what modules are imported

It is not fixed or avoided because it is considered to be working as intended. In the default configuration, any time Python loads modules, it looks for the module in various paths, defined in a list that is accessible as sys.path.

From the documentation:

As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.

In your case, then, path[0] is C:\GitLab\p01, which is definitely not a place to look for standard library modules.

Personally, I am not very happy with the design decision (I would prefer, in particular, that new programmers are forced to get their heads around relative imports ASAP), but it is a conscious design decision, and one that enables quite a bit of convenience.

Is there a way to still keep the names the same but avoid the exception?

If you insist - you can simply hack sys.path:

import sys
local = sys.path.pop(0)
import requests
sys.path.insert(0, local)

This will not necessarily be compatible with any other hacks you might attempt to sys.path anywhere else in the program (but at least you can ensure that the change is immediately reverted after the otherwise-problematic imports). You will be stuck with something like this for every import (optimistically, sequence of imports) that conflicts with the name you want. And, of course, if you want to use the name sys you are out of luck.

You can wrap this up in a variety of ways; and you can hook into the import system in a variety of ways. It is possible (but potentially very dangerous) to do dynamic imports (i.e., from a string that contains a URI), and it is possible to alter the mechanisms that import uses. This is a broad research topic, beyond the scope of a Stack Overflow answer.



Answered By - Karl Knechtel
Answer Checked By - Terry (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing