Re: [Python-Dev] cpython: Introduce importlib.util.ModuleManager which is a context manager to

On Tue, 28 May 2013 23:29:46 +0200 (CEST) brett.cannon <python-checkins@python.org> wrote:
+.. class:: ModuleManager(name) + + A :term:`context manager` which provides the module to load. The module will + either come from :attr:`sys.modules` in the case of reloading or a fresh + module if loading a new module. Proper cleanup of :attr:`sys.modules` occurs + if the module was new and an exception was raised.
What use case does this API solve? (FWIW, I think "ModuleManager" is a rather bad name :-)) Regards Antoine.

On Tue, May 28, 2013 at 5:40 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Tue, 28 May 2013 23:29:46 +0200 (CEST) brett.cannon <python-checkins@python.org> wrote:
+.. class:: ModuleManager(name) + + A :term:`context manager` which provides the module to load. The module will + either come from :attr:`sys.modules` in the case of reloading or a fresh + module if loading a new module. Proper cleanup of :attr:`sys.modules` occurs + if the module was new and an exception was raised.
What use case does this API solve?
See http://bugs.python.org/issue18088 for the other part of this story. I'm basically replacing what importlib.util.module_for_loader does after I realized there is no way in a subclass to override what/how attributes are set on a module before the code object is executed. Instead of using the decorator people will be able to use this context manager with a new method to get the same effect with the ability to better control attribute initialization.
(FWIW, I think "ModuleManager" is a rather bad name :-)
I'm open to suggestions, but the thing does manage the module so it at least makes sense.

On Wed, May 29, 2013 at 10:14 AM, Brett Cannon <brett@python.org> wrote:
(FWIW, I think "ModuleManager" is a rather bad name :-)
I'm open to suggestions, but the thing does manage the module so it at least makes sense.
I suggest ModuleInitialiser as the CM name, with a helper function to make usage read better: with initialise_module(name) as m: # Module initialisation code goes here # Module is rolled back if initialisation fails Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On May 29, 2013 1:09 AM, "Nick Coghlan" <ncoghlan@gmail.com> wrote:
On Wed, May 29, 2013 at 10:14 AM, Brett Cannon <brett@python.org> wrote:
(FWIW, I think "ModuleManager" is a rather bad name :-)
I'm open to suggestions, but the thing does manage the module so it at least makes sense.
I suggest ModuleInitialiser as the CM name, with a helper function to make usage read better:
with initialise_module(name) as m: # Module initialisation code goes here # Module is rolled back if initialisation fails
But you're not initializing the module; more like getting the module, either new or from sys.modules. But I thought ModuleGetter seemed too Java-like. Could hide the class behind a get_module function though.
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Wed, May 29, 2013 at 11:04 PM, Brett Cannon <brett@python.org> wrote:
with initialise_module(name) as m: # Module initialisation code goes here # Module is rolled back if initialisation fails
But you're not initializing the module; more like getting the module, either new or from sys.modules. But I thought ModuleGetter seemed too Java-like. Could hide the class behind a get_module function though.
The point is to provide a useful mnemonic for *why* you would use this context manager, and the reason is because the body of the with statement is going to initialize the contents, and you want to unwind things appropriately if that fails. initializing_module is probably a better name than initialized_module, though (since it isn't initialized yet on entry - instead, that's what should be the case by the end of the statement) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Wed, May 29, 2013 at 10:34 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Wed, May 29, 2013 at 11:04 PM, Brett Cannon <brett@python.org> wrote:
with initialise_module(name) as m: # Module initialisation code goes here # Module is rolled back if initialisation fails
But you're not initializing the module; more like getting the module, either new or from sys.modules. But I thought ModuleGetter seemed too Java-like. Could hide the class behind a get_module function though.
The point is to provide a useful mnemonic for *why* you would use this context manager, and the reason is because the body of the with statement is going to initialize the contents, and you want to unwind things appropriately if that fails.
You should use this context manager to get the correct module to initialize/execute/whatever, e.g. contextlib.closing is about what the context manager is going to do for you, not what you are doing to the object it returned.
initializing_module is probably a better name than initialized_module, though (since it isn't initialized yet on entry - instead, that's what should be the case by the end of the statement)
I am willing to compromise to module_to_initialize, module_to_init, or module_to_load. Pick one. =)

On Thu, May 30, 2013 at 12:47 AM, Brett Cannon <brett@python.org> wrote:
I am willing to compromise to module_to_initialize, module_to_init, or module_to_load. Pick one. =)
I see this as *really* similar to a database transaction, and those start with "session.begin()". Could you tolerate "with begin_module_init(name) as m:"? We could even document the ability to check m.__initializing__ to see whether this is a reload() or not. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, 30 May 2013 00:59:02 +1000, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu, May 30, 2013 at 12:47 AM, Brett Cannon <brett@python.org> wrote:
I am willing to compromise to module_to_initialize, module_to_init, or module_to_load. Pick one. =)
I see this as *really* similar to a database transaction, and those start with "session.begin()".
Could you tolerate "with begin_module_init(name) as m:"?
But for a transaction, it is 'with session', not 'with begin_session'. With 'begin_module_init' I would have no idea what 'm' was. With Brett's 'module_to_init' I have an intuitive idea about what 'm' is. And if 'm' isn't a module, then module_manager would be better. (Note that I haven't grokked what Brett's context manager is actually doing/returning, I'm speaking here as an ignorant reader of someone else's code :)
We could even document the ability to check m.__initializing__ to see whether this is a reload() or not.
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/rdmurray%40bitdance.com

Le Wed, 29 May 2013 11:58:21 -0400, "R. David Murray" <rdmurray@bitdance.com> a écrit :
On Thu, 30 May 2013 00:59:02 +1000, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu, May 30, 2013 at 12:47 AM, Brett Cannon <brett@python.org> wrote:
I am willing to compromise to module_to_initialize, module_to_init, or module_to_load. Pick one. =)
I see this as *really* similar to a database transaction, and those start with "session.begin()".
Could you tolerate "with begin_module_init(name) as m:"?
But for a transaction, it is 'with session', not 'with begin_session'.
or "with transaction.begin()", or "with transaction.commit_on_success()", depending on the API :-)
With 'begin_module_init' I would have no idea what 'm' was. With Brett's 'module_to_init' I have an intuitive idea about what 'm' is.
Agreed. Regards Antoine.

On Wed, May 29, 2013 at 11:58 AM, R. David Murray <rdmurray@bitdance.com> wrote:
On Thu, 30 May 2013 00:59:02 +1000, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu, May 30, 2013 at 12:47 AM, Brett Cannon <brett@python.org> wrote:
I am willing to compromise to module_to_initialize, module_to_init, or module_to_load. Pick one. =)
I see this as *really* similar to a database transaction, and those start with "session.begin()".
Could you tolerate "with begin_module_init(name) as m:"?
But for a transaction, it is 'with session', not 'with begin_session'.
With 'begin_module_init' I would have no idea what 'm' was. With Brett's 'module_to_init' I have an intuitive idea about what 'm' is. And if 'm' isn't a module, then module_manager would be better.
(Note that I haven't grokked what Brett's context manager is actually doing/returning, I'm speaking here as an ignorant reader of someone else's code :)
In case you want to suggest a name, the context manager returns the module that should be initialized/loaded. So typical usage will be:: class Loader: def load_module(self, fullname): with importlib.util.module_to_init(fullname) as module: # Load/initialize the module return module Basically the manager either gets the module from sys.modules if it is already there (a reload) or creates a new module and sticks it into sys.modules so other imports will grab the right module object. If there is an exception and the module was new, it deletes it from sys.modules to prevent stale modules from sticking around.

On Wed, 29 May 2013 12:25:45 -0400, Brett Cannon <brett@python.org> wrote:
In case you want to suggest a name, the context manager returns the module that should be initialized/loaded. So typical usage will be::
class Loader: def load_module(self, fullname): with importlib.util.module_to_init(fullname) as module: # Load/initialize the module return module
Basically the manager either gets the module from sys.modules if it is already there (a reload) or creates a new module and sticks it into sys.modules so other imports will grab the right module object. If there is an exception and the module was new, it deletes it from sys.modules to prevent stale modules from sticking around.
So it is a context manager to handle the exception? Now I think I see where Nick is coming from. How about 'managed_initializiation'? That seems closer to the 'closing' model, to me. It isn't as clear about what it is returning, though, since you are passing it a name and getting back a module, whereas in the closing case you get back the same object you send in. Perhaps 'managed_module'? --David

On Wed, May 29, 2013 at 12:49 PM, R. David Murray <rdmurray@bitdance.com> wrote:
On Wed, 29 May 2013 12:25:45 -0400, Brett Cannon <brett@python.org> wrote:
In case you want to suggest a name, the context manager returns the module that should be initialized/loaded. So typical usage will be::
class Loader: def load_module(self, fullname): with importlib.util.module_to_init(fullname) as module: # Load/initialize the module return module
Basically the manager either gets the module from sys.modules if it is already there (a reload) or creates a new module and sticks it into sys.modules so other imports will grab the right module object. If there is an exception and the module was new, it deletes it from sys.modules to prevent stale modules from sticking around.
So it is a context manager to handle the exception?
It's to choose the right module (sys.modules or new) and if the module is new and there is an exception to delete it from sys.modules (other small details like setting __initializing__ but that's not important). So both __enter__ and __exit__ have logic.
Now I think I see where Nick is coming from.
How about 'managed_initializiation'? That seems closer to the 'closing' model, to me. It isn't as clear about what it is returning, though, since you are passing it a name and getting back a module, whereas in the closing case you get back the same object you send in.
True.
Perhaps 'managed_module'?
managed_module is better than managed_initialization.

On Wed, 29 May 2013 12:55:01 -0400 Brett Cannon <brett@python.org> wrote:
Perhaps 'managed_module'?
managed_module is better than managed_initialization.
I don't understand how it's "managed". "manage", "manager", etc. is the kind of dumb words everybody uses when they don't manage (!) to explain what they're talking about. My vote is for "module_to_init", "uninitialized_module", "pristine_module", etc. Regards Antoine.

On Wed, 29 May 2013 20:10:44 +0200, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Wed, 29 May 2013 12:55:01 -0400 Brett Cannon <brett@python.org> wrote:
Perhaps 'managed_module'?
managed_module is better than managed_initialization.
I don't understand how it's "managed". "manage", "manager", etc. is the kind of dumb words everybody uses when they don't manage (!) to explain what they're talking about.
My vote is for "module_to_init", "uninitialized_module", "pristine_module", etc.
I don't really have a horse in this race (that is, whatever is chosen, my vote will be 0 on it unless someone comes up with something brilliant :), but I'll just point out that those names do not give any clue as to why the thing is a context manager instead of a function that just returns the uninitialized module. --David

On Wed, 29 May 2013 20:10:44 +0200, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Wed, 29 May 2013 12:55:01 -0400 Brett Cannon <brett@python.org> wrote:
Perhaps 'managed_module'?
managed_module is better than managed_initialization.
I don't understand how it's "managed". "manage", "manager", etc. is the kind of dumb words everybody uses when they don't manage (!) to explain what they're talking about.
My vote is for "module_to_init", "uninitialized_module", "pristine_module", etc.
Actually, you are right, 'managed_module' isn't much if any better than those. Our problem is that there are two concepts we are trying to cram into one name: what the context manager is managing, and the object that the context manager gives you on entry to the with block. There probably isn't a good answer. I suppose that one approach would be to have a module_initializer context manager return self and then separately call a method on it it to actually load the module inside the with body. But adding more typing to solve a naming issue seems...odd. --David

On Wed, May 29, 2013 at 2:56 PM, R. David Murray <rdmurray@bitdance.com> wrote:
On Wed, 29 May 2013 20:10:44 +0200, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Wed, 29 May 2013 12:55:01 -0400 Brett Cannon <brett@python.org> wrote:
Perhaps 'managed_module'?
managed_module is better than managed_initialization.
I don't understand how it's "managed". "manage", "manager", etc. is the kind of dumb words everybody uses when they don't manage (!) to explain what they're talking about.
My vote is for "module_to_init", "uninitialized_module", "pristine_module", etc.
I don't like unititionalized_module or pristine_module as that isn't guaranteed thanks to reloading; seems misleading.
Actually, you are right, 'managed_module' isn't much if any better than those.
Our problem is that there are two concepts we are trying to cram into one name: what the context manager is managing, and the object that the context manager gives you on entry to the with block. There probably isn't a good answer.
I suppose that one approach would be to have a module_initializer context manager return self and then separately call a method on it it to actually load the module inside the with body. But adding more typing to solve a naming issue seems...odd.
That would make me feel icky, so I won't do it. So module_to_init it is unless someone can convince me the bikeshed is a different colour.

On Wed, May 29, 2013 at 2:22 PM, Brett Cannon <brett@python.org> wrote:
So module_to_init it is unless someone can convince me the bikeshed is a different colour.
Whatever the name is, it should reflect what is happening during the with statement, and more particularly that the thing will end at the end of the with statement. managed_module() seems fine to me though it could still imply the lifetime of the module rather than the management. During the with statement the module is managed, and I expect it's clear that the management is relative to the import system. However, it could also make sense to split the function into two pieces: getting the module and handling it properly in the face of exceptions in a with statement. So, importlib.util.get_module() and ModuleType.managed(): class Loader: def load_module(self, fullname): module = importlib.util.get_module(fullname) with module.managed(): # Load/initialize the module return module If ModuleType.managed() returned the module, you could do it on one line: class Loader: def load_module(self, fullname): with importlib.util.get_module(fullname).managed() as module: # Load/initialize the module return module On second thought, that "one-liner" is a little too busy. And if it's a problem as a method on ModuleType, make it importlib.util.managed_module(): class Loader: def load_module(self, fullname): module = importlib.util.get_module(fullname) with importlib.util.managed_module(module): # Load/initialize the module return module It would be nice to have both parts in one function. It would be less boilerplate for the "common" case that way, is easier to read, and eliminates the risk of someone not realizing they need both parts. However, I'm not sure it buys us that much, the separate-part approach helps keep the two concepts distinct (for better or for worse), and each piece could be separately useful. Maybe have a third function that wraps the other two or have managed_module() accept strings (and then call get_module() internally). -eric

On 30 May 2013 06:25, "Brett Cannon" <brett@python.org> wrote:
On Wed, May 29, 2013 at 2:56 PM, R. David Murray <rdmurray@bitdance.com>
wrote:
On Wed, 29 May 2013 20:10:44 +0200, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Wed, 29 May 2013 12:55:01 -0400 Brett Cannon <brett@python.org> wrote:
Perhaps 'managed_module'?
managed_module is better than managed_initialization.
I don't understand how it's "managed". "manage", "manager", etc. is the kind of dumb words everybody uses when they don't manage (!) to explain what they're talking about.
My vote is for "module_to_init", "uninitialized_module", "pristine_module", etc.
I don't like unititionalized_module or pristine_module as that isn't guaranteed thanks to reloading; seems misleading.
Actually, you are right, 'managed_module' isn't much if any better than those.
Our problem is that there are two concepts we are trying to cram into one name: what the context manager is managing, and the object that the context manager gives you on entry to the with block. There probably isn't a good answer.
I suppose that one approach would be to have a module_initializer
context
manager return self and then separately call a method on it it to actually load the module inside the with body. But adding more typing to solve a naming issue seems...odd.
That would make me feel icky, so I won't do it.
So module_to_init it is unless someone can convince me the bikeshed is a different colour.
+1 to that bikeshed colour. It covers what we're returning (a module) and what we plan to do with it that needs a with statement (initialising it). Cheers, Nick.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com

On 29/05/13 01:14, Brett Cannon wrote:
On Tue, May 28, 2013 at 5:40 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Tue, 28 May 2013 23:29:46 +0200 (CEST) brett.cannon <python-checkins@python.org> wrote:
+.. class:: ModuleManager(name) + + A :term:`context manager` which provides the module to load. The module will + either come from :attr:`sys.modules` in the case of reloading or a fresh + module if loading a new module. Proper cleanup of :attr:`sys.modules` occurs + if the module was new and an exception was raised.
What use case does this API solve?
See http://bugs.python.org/issue18088 for the other part of this story. I'm basically replacing what importlib.util.module_for_loader does after I realized there is no way in a subclass to override what/how attributes are set on a module before the code object is executed. Instead of using the decorator people will be able to use this context manager with a new method to get the same effect with the ability to better control attribute initialization.
(FWIW, I think "ModuleManager" is a rather bad name :-)
+1. XxxManager is what Java programmers call their classes when they are forced to have an unnecessary class because they don't have 1st class functions or modules. (I don't like 'Context Manager' either, but it's too late to change it :( )
I'm open to suggestions, but the thing does manage the module so it at least makes sense.
But what do you mean by managing? 'Manage' has many meanings. Once you've answered that question you should have your name. Cheers, Mark.

Hi, What about ModuleProxy? From the dictionary: prox·y /ˈpräksē/ Noun The authority to represent someone else, esp. in voting. A person authorized to act on behalf of another. Synonyms deputy - representative - agent - substitute Alfredo On 05/30/2013 10:34 AM, Mark Shannon wrote:
On 29/05/13 01:14, Brett Cannon wrote:
On Tue, May 28, 2013 at 5:40 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Tue, 28 May 2013 23:29:46 +0200 (CEST) brett.cannon <python-checkins@python.org> wrote:
+.. class:: ModuleManager(name) + + A :term:`context manager` which provides the module to load. The module will + either come from :attr:`sys.modules` in the case of reloading or a fresh + module if loading a new module. Proper cleanup of :attr:`sys.modules` occurs + if the module was new and an exception was raised.
What use case does this API solve?
See http://bugs.python.org/issue18088 for the other part of this story. I'm basically replacing what importlib.util.module_for_loader does after I realized there is no way in a subclass to override what/how attributes are set on a module before the code object is executed. Instead of using the decorator people will be able to use this context manager with a new method to get the same effect with the ability to better control attribute initialization.
(FWIW, I think "ModuleManager" is a rather bad name :-)
+1. XxxManager is what Java programmers call their classes when they are forced to have an unnecessary class because they don't have 1st class functions or modules.
(I don't like 'Context Manager' either, but it's too late to change it :( )
I'm open to suggestions, but the thing does manage the module so it at least makes sense.
But what do you mean by managing? 'Manage' has many meanings. Once you've answered that question you should have your name.
Cheers, Mark. _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/asolano%40icai.es

On 05/30/2013 03:34 AM, Mark Shannon wrote:
On 29/05/13 01:14, Brett Cannon wrote:
On Tue, May 28, 2013 at 5:40 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Tue, 28 May 2013 23:29:46 +0200 (CEST) brett.cannon <python-checkins@python.org> wrote:
+.. class:: ModuleManager(name) + + A :term:`context manager` which provides the module to load. The module will + either come from :attr:`sys.modules` in the case of reloading or a fresh + module if loading a new module. Proper cleanup of :attr:`sys.modules` occurs + if the module was new and an exception was raised.
(FWIW, I think "ModuleManager" is a rather bad name :-)
+1. XxxManager is what Java programmers call their classes when they are forced to have an unnecessary class because they don't have 1st class functions or modules.
(I don't like 'Context Manager' either, but it's too late to change it :( )
I'm open to suggestions, but the thing does manage the module so it at least makes sense.
But what do you mean by managing? 'Manage' has many meanings. Once you've answered that question you should have your name.
It manages the context, as in the above reference to context manager. In this case the context is the loading and unloading of a module. Having context managers names end with manager helps indicate how it's used. But other verb+er combinations also work. Taking a hint from the first few words of the __doc__ string gives us an obvious alternative. ModuleProvider Cheers, Ron
participants (8)
-
Alfredo Solano
-
Antoine Pitrou
-
Brett Cannon
-
Eric Snow
-
Mark Shannon
-
Nick Coghlan
-
R. David Murray
-
Ron Adam