File: namespace.py

package info (click to toggle)
python-envisageplugins 3.1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 1,616 kB
  • ctags: 1,970
  • sloc: python: 7,047; makefile: 11; sh: 11; lisp: 1
file content (155 lines) | stat: -rw-r--r-- 4,750 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
""" A Python namespace. """


# Standard library imports.
import os, sys

# Enthought library imports.
from enthought.traits.api import Dict, HasTraits


class Namespace(HasTraits):
    """ A Python namespace. """

    #### 'Namespace' interface ################################################

    # All of the names defined within the module.
    locals = Dict

    # All of the names imported into the module.
    imports = Dict

    # fixme: This is a dict from name -> bool indicating whether a name in
    # locals is a trait or not.  Should locals be a dict containing a tuple?
    _is_trait = Dict
    
    ###########################################################################
    # 'Namespace' interface.
    ###########################################################################
    
    def is_trait(self, name):
        """ Attempt to resolve a name to see if it is a trait. """

        # fixme: We might want to be a bit cleverer than this ;^)
        return True
    
        # Try the namespace's locals first.
        if name in self.locals:
            # These are the definitive traits markers!
            if name in ['TraitFactory', 'Trait', 'Instance']:
                is_trait = True

            # The name won't be in the '_is_trait' dictionary if it was not
            # defined by an assignment i.e., it is a class or function!
            elif not self._is_trait.get(name, False):
                is_trait = False
                
            else:
                next = self.locals[name]
                if len(next.source) > 0:
                    is_trait = self.is_trait(next.source)

                else:
                    is_trait = False

        # Is the name imported?
        elif self.is_imported(name):
            module_name = self.get_next_module_name(name)
            module = self.get_next_module(module_name)

            if module is not None:
                components = name.split('.')
                is_trait = module.is_trait(components[-1])

            else:
                is_trait = False

        # If we have a parent namespace then try that.
        elif self.namespace is not None:
            is_trait = self.namespace.is_trait(name)

        # Otherwise give up!
        else:
            is_trait = False
                
        return is_trait

    def is_imported(self, name):
        """ Returns TRUE if a name is imported. """

        components = name.split('.')

        return components[0] in self.imports

    def get_next_module_name(self, symbol):
        """ Returns the name of the module that a symbol was imported from. """

        components = symbol.split('.')
        if len(components) == 1:
            module_name = self.imports[symbol]
            
        else:
            path = []
            
            # The first component MUST have been imported.
            #
            # An empty string means 'import' as opposed to 'from' used.
            value = self.imports[components[0]]
            if len(value) > 0:
                path.append(value)

                module_name = '.'.join(path)

                return module_name
                
            path.append(components[0])
            
            for component in components[1:-1]:
                path.append(component)

            module_name = '.'.join(path)

        return module_name

    def get_next_module(self, module_name):
        """ Returns a parsed module with the specified name.

        Returns None if the module cannot be found or is 'ignored'.  We ignore
        all modules in the Python core, extension modules etc.

        """

        # fixme: Circular imports!
        from enclbr import find_module, read_file

        # Try to find the module that the symbol came from.
        dirname = os.path.dirname(self.filename)
        filename = find_module(module_name, [dirname] + sys.path)
        
        if filename is not None:
            # If the filename refers to a directory then it must be a
            # package.
            if os.path.isdir(filename):
                filename = os.path.join(filename, '__init__.py')

            # fixme: We should probably put in some more formal filter
            # mechanism here!
            #
            # Ignore extension modules.
            if filename.endswith('.pyd') or filename.endswith('.so'):
                module = None

            # Ignore standard modules.
            elif filename.startswith(sys.prefix):
                module = None

            # Parse it!
            else:
                module = read_file(filename)

        else:
            module = None

        return module
    
#### EOF ######################################################################