Defines utility functions for operating on camel case names.
Provides functions that munge strings to avoid characters that would be problematic in certain situations.
Munge a string to avoid characters that might be problematic as a filename in some filesystems.
Return a timestamp that has been cleansed of characters that might cause problems in filenames, namely colons. If no datetime object is provided, then uses the current time.
Description
The timestamp is in ISO-8601 format with the following exceptions:
Parameters: |
|
---|---|
Returns: |
A string timestamp.
A decorator for marking methods/functions as deprecated.
Live updating of objects in system from module reloads.
The main function exposed by this module is:
refresh(logger=None)
Check for edited python files for modules that are live in the system. If one or more are found, reload the module in such a way that its new class and function definitions are used by all pre-existing objects in the system. This differs from a simple reload(module) which makes no attempt to provide the freshly loaded implementations of classes to objects created with a previous (outdated) version of the class.
This feature allows you to make edits to a module while a program is running and not have to restart the program to get the new behavior in the system. It is particularly handy when working on large GUI applications where you want to update the core code in the system without a lengthy restart.
Example:
# foo.py
class Foo:
def method(self):
print "hello"
$ python
>>> from foo import Foo
>>> obj = Foo()
>>> obj.method()
hello
#<edit file>
# foo.py
class Foo:
def method(self):
print "goodbye"
#<end edit>
>>> import refresh
>>> refresh.refresh()
# obj will now have the behavior of the updated Foo classes.
>>> obj.method()
goodbye
In python, classes and functions are mutable objects. Importing a module instantiates an instance of all the classes and functions defined in the module.
Any objects instantiated from the classes have a obj.__class__ attribute the points to the class they are based upon. When you call a method on the object in your code like so:
obj.method()
python actually calls the method of the __class__ object like so:
obj.__class__.method(obj)
with obj passed in as the “self” argument. This indirection allows us to dynamically change the implementation of method().
When you edit a python module and then reload it in a python session, any classes within the module are reinstantiated within that module and any newly created objects created with a call to module.class() will have the behavior and methods of your freshly edited code. But what about objects that are already “live” in the system that were created with a previous version of module.class? Their __class__ attribute is still pointing at the old version of the class, and so they will have the old behavior. The quickest way to fix this is to find the old class object in the system and replace its attributes and methods with those of the freshly imported class. This will instantly give all old objects in the system the new behavior.
Functions are updated in a similar way. All old versions of functions have their internals (func_code, etc.) replaced with those of the freshly loaded implementation.
Their are multiple issues with trying insert a new class definition back into classes. Doing this clobbers and class scope variables that were set at runtime. Also, this implementation cleans out old classes completely before inserting new method/attributes. That means that any methods dynamically added to a class are also clobbered. There are ways to potentially get around this, but it isn’t clear that it is worth the effort (at least for Enthought applications) as such tricks are not used very often in classes that are often edited. When you do (or anytime you notice suspicious behavior), restart your application.
Enthought people: While refresh() can save you time for working with applications, ALWAYS do a fresh restart and check that everything is working properly before checking edited code in.
Check out why traits classes aren’t cleaned up correctly.
Should we get rid of functions/classes that were in old version of module but aren’t in new one? This could prevent problems with stale functions left around that really weren’t meant to be, but it might also delete functions that “hooked” into a module...
fix me: I think we should to prevent refactor errors.
copyright: | 2005, Enthought, Inc. |
---|---|
author: | Eric Jones |
license: | BSD |
Bases: object
Implementation of refresh(). See referesher.refresh() function for more information.
Filter items for all class objects (not instances mind you)
Filter items for all function objects (not instances mind you)
Filter items for all class and functions objects.
Returns two lists: (functions, classes)
This function is faster than calling filter_functions and filter_classes separately because it only traverses the entire list once to create a sub-list containing both functions and classes. This (usually much shorter) sublist is then traversed again to divide it into functions and classes
Find the names of classes contained within a file.
fix me: This currently only finds top level classes. Nested classes are ignored. ?? Does this really matter much ??
Example:
# foo.py
class Foo:
pass
class Bar:
pass
>>> import traits.util.refresh
>>> refresh.function_and_class_names_in_file('foo.py')
[], ['Foo', 'Bar']
Parse .py file associated with module for class names (full path).
The returned list contains class names without their module name prefix. For example if the foo module contains a Bar class, this method would return [‘Bar’]
Nested classes are not currently supported.
Return a list of the new class within a module
Note that this reloads the module in the process.
Find loaded modules that have been modified since they were loaded.
Searches the modules in sys.modules looks for py files that have a newer timestamp than the associated pyc file. Extension modules are ignored.
Reload edited modules & update existing objects to new versions
Check for edited python files for modules that are live in the system. If one or more are found, reload the module in such a way that its new class and function definitions are used by all pre-existing objects in the system. This differs from a simple reload(module) which makes no attempt to provide the freshly loaded implementations of classes to objects created with a previous (outdated) version of the class.
This feature allows you to make edits to a module while a program is running and not have to restart the program to get the new behavior in the system. It is particularly handy when working on large GUI applications where you want to update the core code in the system without a lengthy restart.
Utility functions for managing and finding resources (ie. images/files etc).
get_path : Returns the absolute path of a class or instance
Creates a name starting with ‘prefix’ that is not in ‘names’.
Returns a file object or file path pointing to the desired resource.
Parameters: |
|
---|---|
Returns: | file (file object or file path) - A file object containing the resource. If return_path is True, ‘file’ will be the full path to the resource. If the file is not found or cannot be opened, None is returned. |
Description
This function will find a desired resource file and return an opened file object. The main method of finding the resource uses the pkg_resources resource_stream method, which searches your working set for the installed project specified and appends the resource_path given to the project path, leading it to the file. If setuptools is not installed or it cannot find/open the resource, find_resource will use the sys.path[0] to find the resource if alt_path is defined.
Returns an absolute path for the specified path.
‘path’ can be a string, class or instance.
Store the content of a resource, given by the name of the projet and the path (relative to the root of the project), into a newly created file.
The first two arguments (project and resource_path) are the same as for the function find_resource in this module. The third argument (filename) is the name of the file which will be created, or overwritten if it already exists. The return value in always None.
A simple topological sort on a dictionary graph.