util Package

util Package

Utility functions, part of the Traits project.

Copyright:2003-2011 Enthought, Inc.

camel_case Module

Defines utility functions for operating on camel case names.

class traits.util.camel_case.CamelCaseToPython[source]

Simple functor class to convert names from camel case to idiomatic Python variable names.

For example::
>>> camel2python = CamelCaseToPython
>>> camel2python('XMLActor2DToSGML')
'xml_actor2d_to_sgml'
traits.util.camel_case.camel_case_to_words(s)[source]

Convert a camel case string into words separated by spaces.

For example::
>>> camel_case_to_words('CamelCase')
'Camel Case'

clean_strings Module

Provides functions that munge strings to avoid characters that would be problematic in certain situations.

traits.util.clean_strings.clean_filename(name)[source]

Munge a string to avoid characters that might be problematic as a filename in some filesystems.

traits.util.clean_strings.clean_timestamp(dt=None, microseconds=False)[source]

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:

  • Colons ‘:’ are replaced by underscores ‘_’.
  • Microseconds are not displayed if the ‘microseconds’ parameter is False.
Parameters:
  • dt (None or datetime.datetime object) –
  • microseconds (bool) – Display microseconds or not.
Returns:

A string timestamp.

traits.util.clean_strings.python_name(name)[source]

Attempt to make a valid Python identifier out of a name.

deprecated Module

A decorator for marking methods/functions as deprecated.

traits.util.deprecated.deprecated(message)[source]

A factory for decorators for marking methods/functions as deprecated.

home_directory Module

traits.util.home_directory.get_home_directory()[source]

Determine the user’s home directory.

refresh Module

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

How It works

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.

Caveats

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.

Questions

  • 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
class traits.util.refresh.Refresher(logger=None)[source]

Bases: object

Implementation of refresh(). See referesher.refresh() function for more information.

refresh()[source]

Find all out-of-date modules and reload functions and classes.

traits.util.refresh.filter_classes(items)[source]

Filter items for all class objects (not instances mind you)

traits.util.refresh.filter_functions(items)[source]

Filter items for all function objects (not instances mind you)

traits.util.refresh.filter_functions_and_classes(items)[source]

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

traits.util.refresh.function_and_class_names_in_file(file_name)[source]

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']
traits.util.refresh.function_and_class_names_in_module(mod)[source]

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.

traits.util.refresh.new_functions_and_classes_for_module(mod, logger=None)[source]

Return a list of the new class within a module

Note that this reloads the module in the process.

traits.util.refresh.out_of_date_modules()[source]

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.

traits.util.refresh.refresh(logger=None)[source]

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.

traits.util.refresh.source_file_for_module(module)[source]

Find the .py file that cooresponds to the module.

resource Module

Utility functions for managing and finding resources (ie. images/files etc).

get_path : Returns the absolute path of a class or instance

create_unique_name : Creates a name with a given prefix that is not in a
given list of existing names. The separator between the prefix and the rest of the name can also be specified (default is a ‘_’)
find_resource: Given a setuptools project specification string
(‘MyProject>=2.1’) and a partial path leading from the projects base directory to the desired resource, will return either an opened file object or, if specified, a full path to the resource.
traits.util.resource.create_unique_name(prefix, names, separator='_')[source]

Creates a name starting with ‘prefix’ that is not in ‘names’.

traits.util.resource.find_resource(project, resource_path, alt_path=None, return_path=False)[source]

Returns a file object or file path pointing to the desired resource.

Parameters:
  • project (string) – The name of the project to look for the resource in. Can be the name or
  • resource_path (string) – The path to the file from inside the package. If the file desired is
  • alt_path (string) – The path to the resource relative to the location of the application’s top-level script (the one with __main__). If this function is called in code/scripts/myscript.py and the resource is code/data/image.jpg, the alt_path would be ‘../data/image.jpg’. This path is only used if the
  • return_path (bool) – Determines whether the function should return a file object or a full path to the resource.
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.

traits.util.resource.get_path(path)[source]

Returns an absolute path for the specified path.

‘path’ can be a string, class or instance.

traits.util.resource.store_resource(project, resource_path, filename)[source]

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.

toposort Module

A simple topological sort on a dictionary graph.

exception traits.util.toposort.CyclicGraph[source]

Bases: exceptions.Exception

Exception for cyclic graphs.

traits.util.toposort.topological_sort(graph)[source]

Returns the nodes in the graph in topological order.