Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Scientific Software
MDANSE
Commits
c0b70ad1
Commit
c0b70ad1
authored
Nov 02, 2016
by
eric pellegrini
Browse files
Merge branch 'release-1.0.3'
parents
45cde0a0
ddb30978
Pipeline
#1121
failed with stages
in 3 minutes and 2 seconds
Changes
316
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
MDANSE/Core/ClassRegistry.py
View file @
c0b70ad1
...
@@ -30,29 +30,15 @@ Created on Mar 30, 2015
...
@@ -30,29 +30,15 @@ Created on Mar 30, 2015
:author: Eric C. Pellegrini
:author: Eric C. Pellegrini
'''
'''
import
abc
import
glob
import
glob
import
imp
import
imp
import
inspect
import
inspect
import
os
import
os
import
sys
import
sys
class
_Meta
(
type
):
from
MDANSE.Core.Singleton
import
Singleton
'''
Metaclass that allows to use the :py:meth:`__getitem__` method at a class level for the class that has been built.
The class that uses this metaclass must define a class attribute named _registry that will be used
by the :py:meth:`__getitem__` method.
'''
def
__getitem__
(
self
,
item
):
"""
Returns a given item stored in the class registry
"""
return
self
.
_registry
[
item
]
class
ClassRegistry
(
abc
.
ABCMeta
):
class
ClassRegistry
(
object
):
'''
'''
Metaclass that registers the classes that make the MDANSE framework.
Metaclass that registers the classes that make the MDANSE framework.
...
@@ -67,49 +53,41 @@ class ClassRegistry(abc.ABCMeta):
...
@@ -67,49 +53,41 @@ class ClassRegistry(abc.ABCMeta):
class attribute will not be registered.
class attribute will not be registered.
'''
'''
__metaclass__
=
_Meta
__metaclass__
=
Singleton
__interfaces
=
set
()
def
__init__
(
self
):
self
.
_registry
=
{}
self
.
_sections
=
{}
def
__setitem__
(
self
,
name
,
cls
):
_registry
=
{}
# The class to be registered must have a class attribute "_registry" to be registered, otherwise return
clsRegistry
=
getattr
(
cls
,
"_registry"
)
def
__init__
(
self
,
name
,
bases
,
namespace
):
if
clsRegistry
is
None
:
'''
return
Constructor
:param name: the name of the class to be built by this metaclass
:type name: str
:param bases: the base classes of the class to be built by this metaclass
:type bases: tuple
:param namespace: the attributes and methods of the class to be built by this metaclass
:type namespace: dict
'''
super
(
ClassRegistry
,
self
).
__init__
(
name
,
bases
,
namespace
)
# And this attribute must be a string for the class to be registerable otherwise return
if
not
isinstance
(
clsRegistry
,
basestring
):
# If the class objet does not have a type attribute, it will not be registered.
return
typ
=
getattr
(
self
,
'type'
,
None
)
if
typ
is
None
:
# Fetch the branch of the registry corresponding the one of the class to be registred, otherwise create a new branch
d
=
self
.
_registry
.
setdefault
(
clsRegistry
,{})
# If a class has already been registered with that name return
if
d
.
has_key
(
name
):
return
return
# If the class object is metaclassed by ClassRegistry then a new section of the registry will
setattr
(
cls
,
"_type"
,
name
)
# be created with its type attribute.
metaClass
=
namespace
.
get
(
"__metaclass__"
,
None
)
d
[
name
]
=
cls
if
metaClass
is
ClassRegistry
:
ClassRegistry
.
__interfaces
.
add
(
self
)
def
__getitem__
(
self
,
name
):
if
(
ClassRegistry
.
_registry
.
has_key
(
typ
)):
return
return
self
.
_registry
.
get
(
name
,{})
ClassRegistry
.
_registry
[
typ
]
=
{}
def
update
(
self
,
packageDir
):
else
:
for
interface
in
ClassRegistry
.
__interfaces
:
if
issubclass
(
self
,
interface
):
ClassRegistry
.
_registry
[
interface
.
type
][
typ
]
=
self
break
@
classmethod
def
update_registry
(
cls
,
packageDir
):
'''
'''
Update the classes registry by importing all the modules contained in a given package.
Update the classes registry by importing all the modules contained in a given package.
...
@@ -141,10 +119,8 @@ class ClassRegistry(abc.ABCMeta):
...
@@ -141,10 +119,8 @@ class ClassRegistry(abc.ABCMeta):
else
:
else
:
if
os
.
path
.
abspath
(
os
.
path
.
dirname
(
mod
.
__file__
))
!=
os
.
path
.
abspath
(
moduleDir
):
if
os
.
path
.
abspath
(
os
.
path
.
dirname
(
mod
.
__file__
))
!=
os
.
path
.
abspath
(
moduleDir
):
print
"A module with name %s is already present in your distribution with %s path."
%
(
moduleName
,
moduleDir
)
print
"A module with name %s is already present in your distribution with %s path."
%
(
moduleName
,
moduleDir
)
@
classmethod
def
info
(
self
,
interface
):
def
info
(
cls
,
interface
):
'''
'''
Returns informations about the subclasses of a given base class stored in the registry.
Returns informations about the subclasses of a given base class stored in the registry.
...
@@ -155,7 +131,7 @@ class ClassRegistry(abc.ABCMeta):
...
@@ -155,7 +131,7 @@ class ClassRegistry(abc.ABCMeta):
:rtype: str
:rtype: str
'''
'''
if
not
cls
.
_registry
.
has_key
(
interface
):
if
not
self
.
_registry
.
has_key
(
interface
):
return
"The interface "
+
interface
+
" is not registered"
return
"The interface "
+
interface
+
" is not registered"
words
=
[
"Name"
,
"Class"
,
"File"
]
words
=
[
"Name"
,
"Class"
,
"File"
]
...
@@ -168,7 +144,7 @@ class ClassRegistry(abc.ABCMeta):
...
@@ -168,7 +144,7 @@ class ClassRegistry(abc.ABCMeta):
maxlength
=
-
1
maxlength
=
-
1
# Loop over the registry items.
# Loop over the registry items.
for
i
,
(
k
,
v
)
in
enumerate
(
sorted
(
cls
.
_registry
[
interface
].
items
())):
for
i
,
(
k
,
v
)
in
enumerate
(
sorted
(
self
.
_registry
[
interface
].
items
())):
# Get the module corresponding to the job class.
# Get the module corresponding to the job class.
mod
=
inspect
.
getmodule
(
v
)
mod
=
inspect
.
getmodule
(
v
)
...
@@ -185,8 +161,8 @@ class ClassRegistry(abc.ABCMeta):
...
@@ -185,8 +161,8 @@ class ClassRegistry(abc.ABCMeta):
return
contents
.
format
(
maxlength
,
*
words
)
return
contents
.
format
(
maxlength
,
*
words
)
@
classmethod
@
property
def
get_
interfaces
(
cls
):
def
interfaces
(
self
):
'''
'''
Returns the interfaces that are currently registered.
Returns the interfaces that are currently registered.
...
@@ -194,4 +170,8 @@ class ClassRegistry(abc.ABCMeta):
...
@@ -194,4 +170,8 @@ class ClassRegistry(abc.ABCMeta):
:rtype: list of str
:rtype: list of str
'''
'''
return
sorted
(
cls
.
_registry
.
keys
())
return
sorted
(
self
.
_registry
.
keys
())
\ No newline at end of file
REGISTRY
=
ClassRegistry
()
MDANSE/Data/ElementsDatabase.py
View file @
c0b70ad1
...
@@ -35,6 +35,8 @@ import copy
...
@@ -35,6 +35,8 @@ import copy
import
csv
import
csv
import
numbers
import
numbers
import
os
import
os
import
pkg_resources
import
sys
import
xml.etree.ElementTree
as
etree
import
xml.etree.ElementTree
as
etree
from
MDANSE.Core.Platform
import
PLATFORM
from
MDANSE.Core.Platform
import
PLATFORM
...
@@ -111,8 +113,14 @@ class ElementsDatabase(object):
...
@@ -111,8 +113,14 @@ class ElementsDatabase(object):
__metaclass__
=
Singleton
__metaclass__
=
Singleton
# The default path
try
:
_DEFAULT_DATABASE
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
"elements_database.csv"
)
_DEFAULT_DATABASE
=
pkg_resources
.
resource_filename
(
__name__
,
"elements_database.csv"
)
except
:
if
hasattr
(
sys
,
'frozen'
):
_DEFAULT_DATABASE
=
os
.
path
.
join
(
os
.
path
.
dirname
(
sys
.
executable
),
"elements_database.csv"
)
else
:
raise
# The user path
# The user path
_USER_DATABASE
=
os
.
path
.
join
(
PLATFORM
.
application_directory
(),
"elements_database.csv"
)
_USER_DATABASE
=
os
.
path
.
join
(
PLATFORM
.
application_directory
(),
"elements_database.csv"
)
...
...
MDANSE/Externals/__init__.py
View file @
c0b70ad1
...
@@ -28,7 +28,6 @@
...
@@ -28,7 +28,6 @@
This package contains all the externals dependencies of MDANSE. It contains:
This package contains all the externals dependencies of MDANSE. It contains:
#. magnitude: a package for handling units
#. magnitude: a package for handling units
#. pubsub: a package that implements the publisher subscriber mechanism
#. pyparsing: a package for creating and executing simple grammar
#. pyparsing: a package for creating and executing simple grammar
#. svgfig: a package for handling SVG file format
#. svgfig: a package for handling SVG file format
...
...
MDANSE/Externals/pubsub/LICENSE_BSD_Simple.txt
deleted
100644 → 0
View file @
45cde0a0
Copyright (c) since 2006, Oliver Schoenborn
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MDANSE/Externals/pubsub/RELEASE_NOTES.txt
deleted
100644 → 0
View file @
45cde0a0
For PyPubSub v3.3.0
^^^^^^^^^^^^^^^^^^^^^
* cleanup low-level API: exception classes, moved some out of pub module that did not
belong there (clutter), move couple modules,
* completed the reference documentation
* support installation via pip
* follow some guidelines in some PEPs such as PEP 396 and PEP 8
* support Python 2.6, 2.7, and 3.2 to 3.4a4 but drop support for Python <= 2.5
For PyPubSub v3.2.0
^^^^^^^^^^^^^^^^^^^
This is a minor release for small improvements made (see docs/CHANGELOG.txt)
based on feedback from user community. In particular an XML reader for
topic specification contributed by Josh English. Also cleaned up the
documentation, updated the examples folder (available in source distribution
as well as `online`_).
.. _online: https://sourceforge.net/p/pubsub/code/HEAD/tree/
Only 3 changes to API (function names):
* renamed pub.getDefaultRootAllTopics to pub.getDefaultTopicTreeRoot
* removed pub.importTopicTree: use pub.addTopicDefnProvider(source, format)
* renamed pub.exportTopicTree to pub.exportTopicTreeSpec
Oliver Schoenborn
September 2013
PyPubSub 3.1.2
^^^^^^^^^^^^^^^^
This is a minor release for small improvements made (see docs/CHANGELOG.txt)
based on feedback from user community. Also extended the documentation. See
pubsub.sourceforge.net for installation and usage. See the examples folder for
some useful examples.
Oliver Schoenborn
Nov 2011
PyPubSub 3.1.1b1
^^^^^^^^^^^^^^^^^^
Docs updated.
Oliver Schoenborn
May 2010
For PyPubSub v3.1.0b1
^^^^^^^^^^^^^^^^^^^^^^
Major cleanup of the API since 3.0 and better support
for the legacy wxPython code. Defining a topic tree
via a text file has been improved drastically, making it
simpler to document topic messages and payload data
required or optional. More examples have been added,
and the messaging protocols clarified.
The included docs are not yet updated, that's what I'm
working on now and will lead to the 3.1.1b1 release.
I'm also working on an add-on module that would allow
two applications to communicate over the network using
pubsub-type messaging (with topics, etc). The design
is almost complete.
Oliver Schoenborn
Jan 2010
\ No newline at end of file
MDANSE/Externals/pubsub/__init__.py
View file @
c0b70ad1
"""
'''
Pub
sub package initialization.
Pub
lish-subscribe package.
:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved.
This package provides the following modules:
:license: BSD, see LICENSE_BSD_Simple.txt for details.
"""
_PREVIOUS_RELEASE_DATE
=
"2013-09-15"
- pub: "entry point" module for core pubsub functionality. It provides
_PREVIOUS_RELEASE_VER
=
"3.2.1b"
functions for sending messages and subscribing listeners and various
others.
- utils: subpackage of utility functions and classes for debugging
messages, handling exceptions raised in listeners, and more.
- setupv1: (deprecated) module to force pubsub to use the old,
"version 1" (aka v1) API (should only be useful to wxPython users
for legacy code).
- setuparg1: module to setup pubsub to use "arg1" messaging protocol
- setupkwargs: module to setup pubsub to use "kwargs" messaging protocol
For instance::
from pubsub import pub
pub.sendMessage('topic', data1=123)
:copyright: Copyright 2006-2009 by Oliver Schoenborn, all rights reserved.
:license: BSD, see LICENSE.txt for details.
Last known commit:
- $Date: 2010-02-13 08:57:21 -0500 (Sat, 13 Feb 2010) $
- $Revision: 249 $
'''
__version__
=
"3.3.0"
__all__
=
[
__all__
=
[
'pub'
,
'pub'
,
'utils'
,
'utils'
,
'printImported'
,
'setupkwargs'
,
'setuparg1'
,
'setupv1'
,
'setupkwargs'
,
'setuparg1'
,
'__version__'
]
]
# set our module search path in globalsettings so setup*.py modules
# can find and modify
from
MDANSE.Externals.pubsub
import
pubsubconf
pubsubconf
.
setPubsubInfo
(
__path__
,
globals
())
#del pubsubconf # prevent circular ref
def
printImported
():
'''Output a list of pubsub modules imported so far'''
import
sys
ll
=
[
mod
for
mod
in
sys
.
modules
.
keys
()
if
mod
.
find
(
'pubsub'
)
>=
0
]
ll
.
sort
()
print
'
\n
'
.
join
(
ll
)
def
_tryAutoSetupV1
():
'''This function is called automatically when the pubsub module is
imported. It determines if the legacy "version 1" API of pubsub should
be used automatically, by looking for a module called 'autosetuppubsubv1'
on the module's search path. If this module is found, setupv1 is imported,
so your application will get v1 API just by doing "from pubsub import ...".
If that module is not found then nothing happens and the function
returns; your application will get the "default" API unless you
explicitly choose a different one. Note that autosetuppubsubv1 is never
actually imported, just searched. '''
try
:
# if autosetupv1 is importable, then it means we should
# automatically setup for version 1 API
import
imp
imp
.
find_module
(
'autosetuppubsubv1'
,
__path__
)
except
ImportError
:
pass
else
:
from
MDANSE.Externals.pubsub
import
setupv1
assert
pub
is
not
None
assert
Publisher
is
pub
.
Publisher
_tryAutoSetupV1
()
MDANSE/Externals/pubsub/autosetuppubsubv1.py
0 → 100644
View file @
c0b70ad1
'''
If this module is named autosetuppubsubv1, and it is in the pubsub
package's folder, it will cause pubsub to default to "version 1" (v1)
of the API when pub is imported. The v1 API was the version originally
developed as part of wxPython's wx.lib library.
If this module is named anything else (such as prefixed with an
underscore) it will not be found by pubsub: the most recent pubsub
API will be loaded upon import of the *pub* module.
'''
\ No newline at end of file
MDANSE/Externals/pubsub/core/__init__.py
View file @
c0b70ad1
"""
'''
Core package of pubsub, holding the publisher, listener, and topic
Core package of pubsub, holding the publisher, listener, and topic
object modules. Functions defined here are used internally by
object modules. Functions defined here are used internally by
pubsub so that the right modules can be found later, based on the
pubsub so that the right modules can be found later, based on the
selected messaging protocol.
selected messaging protocol.
Indeed some of the API depends on the messaging
Indeed some of the API depends on the messaging
protocol used. For instance sendMessage(), defined in publisher.py,
protocol used. For instance sendMessage(), defined in publisher.py,
has a different signature (and hence implementation) for the kwargs
has a different signature (and hence implementation) for the kwargs
protocol than for the arg1 protocol.
protocol than for the arg1 protocol.
The most convenient way to
The most convenient way to
support this is to put the parts of the package that differ based
support this is to put the parts of the package that differ based
on protocol in separate folder, and add one of those folders to
on protocol in separate folders, and add one of those folders to
the package's __path__ variable (defined automatically by the Python
the package's __path__ variable (defined automatically by the Python
interpreter when __init__.py is executed). For instance, code
interpreter when __init__.py is executed). For instance, code
specific to the kwargs protocol goes in the kwargs folder, and code
specific to the kwargs protocol goes in the kwargs folder, and code
specific to the arg1 protocol in the arg1 folder. Then when doing
specific to the arg1 protocol in the arg1 folder. Then when doing
"from pubsub.core import listener", the correct listener.py will be
"from pubsub.core import listener", the correct listener.py will be
found for the specified protocol. The default protocol is kwargs.
found for the specified protocol. The default protocol is kwargs.
Only one protocol can be used in an application. The default protocol,
Only one protocol can be used in an application. The default protocol,
if none is chosen by user, is kwargs, as selected by the call to
if none is chosen by user, is kwargs, as selected by the call to
_prependModulePath() at end of this file.
_prependModulePath() at end of this file.
:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved.
:copyright: Copyright 2006-2009 by Oliver Schoenborn, all rights reserved.
:license: BSD, see LICENSE_BSD_Simple.txt for details.
:license: BSD, see LICENSE.txt for details.
"""
'''
from
MDANSE.Externals.pubsub.core
import
policies
def
_prependModulePath
(
extra
):
"""Insert extra at beginning of package's path list. Should only be
def
setMsgProtocol
(
protocol
):
called once, at package load time, to set the folder used for
implementation specific to the default message protocol."""
policies
.
msgDataProtocol
=
protocol
corepath
=
__path__
initpyLoc
=
corepath
[
-
1
]
# add appropriate subdir for protocol-specific implementation
import
os
if
protocol
==
'kwargs'
:
corepath
.
insert
(
0
,
os
.
path
.
join
(
initpyLoc
,
extra
))
_replaceModulePath0
(
'kwargs'
)
else
:
# add appropriate subdir for protocol-specific implementation
_replaceModulePath0
(
'arg1'
)
from
..
import
policies
_prependModulePath
(
policies
.
msgDataProtocol
)
def
setMsgDataArgName
(
stage
,
listenerArgName
,
senderArgNameAny
=
False
):
from
.publisher
import
Publisher
policies
.
senderKwargNameAny
=
senderArgNameAny
from
.callables
import
(
policies
.
msgDataArgName
=
listenerArgName
AUTO_TOPIC
,
policies
.
msgProtocolTransStage
=
stage
)
#print `policies.msgProtocolTransStage`, `policies.msgDataProtocol`, \
# `policies.senderKwargNameAny`, `policies.msgDataArgName`
from
.listener
import
(
#print 'override "arg1" protocol arg name:', argName
Listener
,
getID
as
getListenerID
,
ListenerMismatchError
,
def
_replaceModulePath0
(
dirname
):
IListenerExcHandler
,
'''Replace the first package-path item (in __path__) with dirname.
)
The dirname will be prepended with the package's path, assumed to
be the last item in __path__.'''
from
.topicobj
import
(
corepath
=
__path__
Topic
,
assert
len
(
corepath
)
>
1
SenderMissingReqdMsgDataError
,
initpyLoc
=
corepath
[
-
1
]
SenderUnknownMsgDataError
,
import
os
MessageDataSpecError
,
corepath
[
0
]
=
os
.
path
.
join
(
initpyLoc
,
dirname
)
TopicDefnError
,
ExcHandlerError
,
)
def
_prependModulePath
(
extra
):
'''Insert extra at beginning of package's path list. Should only be
from
.topicmgr
import
(
called once, at package load time, to set the folder used for
TopicManager
,
implementation specific to the default message protocol.'''
TopicDefnError
,
corepath
=
__path__
TopicNameError
,
initpyLoc
=
corepath
[
-
1
]
ALL_TOPICS
,
import
os
)
corepath
.
insert
(
0
,
os
.
path
.
join
(
initpyLoc
,
extra
))
from
.topicdefnprovider
import
(
ITopicDefnProvider
,
# default protocol:
TopicDefnProvider
,
_prependModulePath
(
'kwargs'
)
ITopicDefnDeserializer
,
UnrecognizedSourceFormatError
,
exportTopicTreeSpec
,
TOPIC_TREE_FROM_MODULE
,
TOPIC_TREE_FROM_STRING
,
TOPIC_TREE_FROM_CLASS
,
)
from
.topictreetraverser
import
(
TopicTreeTraverser
,
)
from
.notificationmgr
import
(
INotificationHandler
,
)
\ No newline at end of file
MDANSE/Externals/pubsub/core/arg1/__init__.py
View file @
c0b70ad1
"""
'''
This is not really a package init file, it is only here to simplify the
This is not really a package init file, it is only here to simplify the
packaging and installation of pubsub.core's protocol-specific subfolders
packaging and installation of pubsub.core's protocol-specific subfolders
by setuptools. The python modules in this folder are automatically made
by setuptools. The python modules in this folder are automatically made
part of pubsub.core via pubsub.core's __path__. Hence, this should not
part of pubsub.core via pubsub.core's __path__. Hence, this should not
be imported directly, it is part of pubsub.core when the messaging
be imported directly, it is part of pubsub.core when the messaging
protocol is "arg1" (and not usable otherwise).
protocol is "arg1" (and not usable otherwise).
:copyright: Copyright
since 2006
by Oliver Schoenborn, all rights reserved.
:copyright: Copyright
2006-2009
by Oliver Schoenborn, all rights reserved.