This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Importlib reload by module name (String)
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.10
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, eric.snow, ncoghlan, serhiy.storchaka, stefan.mosoi
Priority: normal Keywords:

Created on 2021-01-27 12:14 by stefan.mosoi, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (6)
msg385765 - (view) Author: Stefan Mosoi (stefan.mosoi) Date: 2021-01-27 12:14
Weird behaviour (maybe it's my opinion) in reload from importlib

if i do:
import importlib
import sys
import datetime
importlib.reload(datetime.timedelta.__module__)

I get
Typeerror: reload() argument must be a module

but if i do

import importlib
import sys
import datetime
importlib.reload(sys.modules.get(datetime.timedelta.__module__))

it works.

The sys.modules.get i got from reload() code:
def reload(module)
    if not module or not isinstance(module, types.ModuleType):
        raise TypeError("reload() argument must be a module")
    try:
        name = module.__spec__.name
    except AttributeError:
        name = module.__name__

    if sys.modules.get(name) is not module:

It wouldn't be easier to check if string do sys.modules.get ?

And as a bonus a reload_module function that gets a class (or anything with __module__ and reloads that module, no question asked?) 

And i know it's easy to implement, but it would be nicer if was better handled in the lib :)

Notes (if it matters):
Python 3.9.1 x64 Windows
I didn't test on other versions.
msg385773 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-01-27 13:37
It works as documented. reload() argument must be a module. If you have only module name, sys.modules is a mapping of module names to modules. It is trivial to combine two things in one line.

And why do you want to reload a module by name (without having a reference to module itself)? In general, reload() should be used with caution, it is easy to misuse it.
msg385778 - (view) Author: Stefan Mosoi (stefan.mosoi) Date: 2021-01-27 14:35
The motivation behind my request is as follow: 
I have a dynamic set class (i don't "know" it) and calling
__module__ for that class return a string, reload requires Module(and i don't think __module__ will be changed to module). The other functions (import, import_module) recieve a string. 
 
Maybe is trivial to add a one liner, but it's a bit confusing to call another function in another module than importlib.

Also (not from what i found when searching) there is no way to get the module from name without using import_module/import. 

maybe i found the solution, but there might be others that aren't so lucky.
msg385781 - (view) Author: Stefan Mosoi (stefan.mosoi) Date: 2021-01-27 14:59
Also 
> without having a reference to module itself

reload() just gets the name of the module

    try:
        name = module.__spec__.name
    except AttributeError:
        name = module.__name__

and then 

if sys.modules.get(name) is not module

So it might be just check if is str just skip the tranformation to string.
msg385803 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2021-01-27 19:04
Thanks for the idea, Stefan, but I'm going to close this as something we don't want to do. `importlib.reload()` purposefully takes a module object as that's what is going to get mutated/changed and it must already exist. The other importlib functions take a string because the module might not even exist yet.

And as Serhiy said, reloading is a bit dangerous and shouldn't be taken lightly. It primarily exists to reload a module when you're working in the REPL and editing a file live, not for anything fancy during execution of production code. So keeping it squarely targeted the REPL case and making it a bit harder for other cases is a good thing in my opinion.
msg385805 - (view) Author: Stefan Mosoi (stefan.mosoi) Date: 2021-01-27 19:14
I understand. 
I was using to reload some classes that might have changed/added (updates and stuff) without having to reload the hole project. There might be some other ways (i found this, and didn't keep researching after).
The documentation didn't warned / informed about real live usage or intentions for this to exist(like in REPL).

I will continue using this as i use it now and i fully accept the consequences. 

Thank you for the time and answers.
History
Date User Action Args
2022-04-11 14:59:40adminsetgithub: 87203
2021-01-27 19:14:36stefan.mosoisetmessages: + msg385805
2021-01-27 19:04:41brett.cannonsetstatus: open -> closed
versions: + Python 3.10, - Python 3.9
messages: + msg385803

resolution: rejected
stage: resolved
2021-01-27 14:59:33stefan.mosoisetmessages: + msg385781
2021-01-27 14:35:17stefan.mosoisetmessages: + msg385778
2021-01-27 13:37:53serhiy.storchakasetnosy: + eric.snow, serhiy.storchaka, brett.cannon, ncoghlan
messages: + msg385773
2021-01-27 12:14:36stefan.mosoicreate