Giter Site home page Giter Site logo

apptools's People

Contributors

aaronayres35 avatar cfarrow avatar corranwebster avatar dependabot[bot] avatar dpinte avatar gaelvaroquaux avatar itziakos avatar johntyree avatar jwiggins avatar kitchoi avatar larsoner avatar mattions avatar mchilvers avatar mdickinson avatar mechworrior avatar onny avatar pberkes avatar prabhuramachandran avatar pradyunsg avatar punchagan avatar rahulporuri avatar rkern avatar rmcgibbo avatar scopatz avatar snegovikufa avatar stefanoborini avatar stewbond avatar swt2c avatar tonysyu avatar warrenweckesser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apptools's Issues

Test failures with PYTHONHASHSEED=random.

There are several (random, of course) test failures when running the test suite with PYTHONHASHSEED=random, indicating that we've got dictionary-order dependencies either in the core code (bad), or the test-suite (not so bad, but should still be fixed). An example test run is below.

(Canopy 64bit) taniyama:apptools mdickinson$ PYTHONHASHSEED=random nosetests .
............................................................................................................F.............F..............F..............F.............F................F...EF.F....................F........................................................................................................................................................................
======================================================================
ERROR: Test if classic classes can be pickled.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/persistence/tests/test_state_pickler.py", line 245, in test_pickle_classic
    self.verify(t, state)
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/persistence/tests/test_state_pickler.py", line 112, in verify
    self.assertEqual(lst[-1]['data']['data']['a'], 'b')
TypeError: 'NoneType' object has no attribute '__getitem__'

======================================================================
FAIL: test retrieving the names of bound objects
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/naming/tests/context_test_case.py", line 514, in test_search
    self.assertEqual( names, ['one', 'sub/sub sub/one'] )
AssertionError: Lists differ: ['sub/sub sub/one', 'one'] != ['one', 'sub/sub sub/one']

First differing element 0:
sub/sub sub/one
one

- ['sub/sub sub/one', 'one']
+ ['one', 'sub/sub sub/one']

======================================================================
FAIL: test retrieving the names of bound objects
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/naming/tests/context_test_case.py", line 514, in test_search
    self.assertEqual( names, ['one', 'sub/sub sub/one'] )
AssertionError: Lists differ: ['sub/sub sub/one', 'one'] != ['one', 'sub/sub sub/one']

First differing element 0:
sub/sub sub/one
one

- ['sub/sub sub/one', 'one']
+ ['one', 'sub/sub sub/one']

======================================================================
FAIL: test retrieving the names of bound objects
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/naming/tests/context_test_case.py", line 514, in test_search
    self.assertEqual( names, ['one', 'sub/sub sub/one'] )
AssertionError: Lists differ: ['sub/sub sub/one', 'one'] != ['one', 'sub/sub sub/one']

First differing element 0:
sub/sub sub/one
one

- ['sub/sub sub/one', 'one']
+ ['one', 'sub/sub sub/one']

======================================================================
FAIL: test retrieving the names of bound objects
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/naming/tests/context_test_case.py", line 514, in test_search
    self.assertEqual( names, ['one', 'sub/sub sub/one'] )
AssertionError: Lists differ: ['sub/sub sub/one', 'one'] != ['one', 'sub/sub sub/one']

First differing element 0:
sub/sub sub/one
one

- ['sub/sub sub/one', 'one']
+ ['one', 'sub/sub sub/one']

======================================================================
FAIL: test retrieving the names of bound objects
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/naming/tests/context_test_case.py", line 514, in test_search
    self.assertEqual( names, ['one', 'sub/sub sub/one'] )
AssertionError: Lists differ: ['sub/sub sub/one', 'one'] != ['one', 'sub/sub sub/one']

First differing element 0:
sub/sub sub/one
one

- ['sub/sub sub/one', 'one']
+ ['one', 'sub/sub sub/one']

======================================================================
FAIL: Test if we are able to dump the state to a string.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/persistence/tests/test_spickle.py", line 48, in test_dump_state
    self.assertEqual(str, str1)
AssertionError: "ccopy_reg\n_reconstructor\np0\n(ctest_spickle\nFoo\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'a'\np6\n(itest_spickle\nA\np7\n(dp8\nS'array'\np9\ncnumpy.core.multiarray\n_reconstruct\np10\n(cnumpy\nndarray\np11\n(I0\ntp12\nS'b'\np13\ntp14\nRp15\n(I1\n(I5\ntp16\ncnumpy\ndtype\np17\n(S'f8'\np18\nI0\nI1\ntp19\nRp20\n(I3\nS'<'\np21\nNNNI-1\nI-1\nI0\ntp22\nbI00\nS'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xd0?\\x00\\x00\\x00\\x00\\x00\\x00\\xe0?\\x00\\x00\\x00\\x00\\x00\\x00\\xe8?\\x00\\x00\\x00\\x00\\x00\\x00\\xf0?'\np23\ntp24\nbsg6\nI100\nsg13\nI200\nsbsg13\nctraits.traits\n__newobj__\np25\n(ctest_spickle\nB\np26\ntp27\nRp28\n(dp29\nS'f'\np30\nF2.0\nsS'i'\np31\nI20\nsS'__traits_version__'\np32\nS'4.5.0'\np33\nsbsS'ref'\np34\ng7\nsb." != "ccopy_reg\n_reconstructor\np0\n(ctest_spickle\nFoo\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'a'\np6\n(itest_spickle\nA\np7\n(dp8\nS'array'\np9\ncnumpy.core.multiarray\n_reconstruct\np10\n(cnumpy\nndarray\np11\n(I0\ntp12\nS'b'\np13\ntp14\nRp15\n(I1\n(I5\ntp16\ncnumpy\ndtype\np17\n(S'f8'\np18\nI0\nI1\ntp19\nRp20\n(I3\nS'<'\np21\nNNNI-1\nI-1\nI0\ntp22\nbI00\nS'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xd0?\\x00\\x00\\x00\\x00\\x00\\x00\\xe0?\\x00\\x00\\x00\\x00\\x00\\x00\\xe8?\\x00\\x00\\x00\\x00\\x00\\x00\\xf0?'\np23\ntp24\nbsg6\nI100\nsg13\nI200\nsbsg13\nctraits.traits\n__newobj__\np25\n(ctest_spickle\nB\np26\ntp27\nRp28\n(dp29\nS'i'\np30\nI20\nsS'f'\np31\nF2.0\nsS'__traits_version__'\np32\nS'4.5.0'\np33\nsbsS'ref'\np34\ng7\nsb."

======================================================================
FAIL: Test if traited classes can be pickled.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/persistence/tests/test_state_pickler.py", line 320, in test_pickle_traits
    self.verify(t, state)
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/persistence/tests/test_state_pickler.py", line 110, in verify
    self.assertEqual(lst[-1]['type'], 'instance')
AssertionError: 'reference' != 'instance'

======================================================================
FAIL: Test if the state can be saved like the object itself.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/persistence/tests/test_state_pickler.py", line 367, in test_state_is_saveable
    self.verify_state(state1, state)
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/persistence/tests/test_state_pickler.py", line 183, in verify_state
    self.assertEqual(state.inst.__metadata__, state1.inst.__metadata__)
AssertionError: {'initargs': (), 'version': [(('A', 'test_state_pickler'), -1)], 'module': 'test [truncated]... != {'initargs': (), 'version': [(('A', 'test_state_pickler'), -1)], 'module': 'test [truncated]...
  {'class_name': 'A',
   'has_instance': True,
-  'id': 5,
?        ^

+  'id': 4,
?        ^

   'initargs': (),
   'module': 'test_state_pickler',
   'type': 'instance',
   'version': [(('A', 'test_state_pickler'), -1)]}

======================================================================
FAIL: preferences node changed
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/mdickinson/Enthought/ETS/apptools/apptools/preferences/tests/preferences_helper_test_case.py", line 438, in test_preferences_node_changed
    self.assertEqual('width', listener.trait_name)
AssertionError: 'width' != 'bgcolor'
-------------------- >> begin captured logging << --------------------
apptools.preferences.preferences: DEBUG: loading preferences from </Users/mdickinson/Enthought/ETS/apptools/apptools/preferences/tests/example.ini>
apptools.preferences.preferences: DEBUG: loading preferences from </Users/mdickinson/Enthought/ETS/apptools/apptools/preferences/tests/example.ini>
--------------------- >> end captured logging << ---------------------

----------------------------------------------------------------------
Ran 380 tests in 1.234s

FAILED (errors=1, failures=9)

apptools.preferences does not support storing unicode values.

Exception occurred in traits notification handler for object: <Preferences object at 0x40c19b0>, trait: last_name, old value: value, new value: TestUÜöser
Traceback (most recent call last):
  File "lib/python2.7/site-packages/traits/trait_notifiers.py", line 340, in __call__
    self.handler( *args )
  File "lib/python2.7/site-packages/apptools/preferences/preferences_helper.py", line 71, in _anytrait_changed
    self.preferences.set('%s.%s' % (self._get_path(), trait_name), new)
  File "lib/python2.7/site-packages/apptools/preferences/scoped_preferences.py", line 166, in set
    node.set(path, value)
  File "lib/python2.7/site-packages/apptools/preferences/preferences.py", line 191, in set
    node.set('.'.join(components[1:]), value)
  File "lib/python2.7/site-packages/apptools/preferences/preferences.py", line 185, in set
    self._set(path, value)
  File "lib/python2.7/site-packages/apptools/preferences/preferences.py", line 546, in _set
    value = str(value)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 5-6: ordinal not in range(128)

Fix multiple versioned pickle wrappers

Apptools provides the sweet_pickle subpackage to handle versioning of pickled objects to allow unpickling of objects after changes to the class structure.

The persistence subpackage has a slightly different focus: it is more about extracting state as a dictionary, but it has similar themes.

Mayavi uses persistence, but it also uses apptools.naming which internally uses sweet_pickle, so we cannot simply deprecate sweet_pickle.

Convert test suite to use unittest

The test suite is currently based on nose. nose is no longer maintained. There's a successor, nose2, but that doesn't pick up all the apptools tests right now. (Out of the box, nose finds 401 tests, while nose2 finds 174. That may be tweakable.)

We should consider converting all the tests to regular unittest testcases (and then users can still choose to use whichever test runner they prefer).

Consider making traitsui an optional requirement

Projects that don't use the GUI parts of apptools are still required to install traitsui if they want to have an environment where all the dependencies are met:

09:56 $ edm install apptools
Fetching indices for package repositories.... done

The following packages will be installed:

    apptools   4.4.0-4   787     KiB
    configobj  5.0.6-2    70     KiB
    pyface     5.1.0-5     1.5   MiB
    pygments   2.1.3-1     1.73  MiB
    six        1.10.0-1   19     KiB
    traits     4.6.0-1   636     KiB
    traitsui   5.1.0-2     1.5   MiB

Do you want to continue ? [Y/n]:

PreferencesHelper sets *_items preference for List preferences

Version info (although the same problem essentially exists with traits v6.0.0):

$ edm list | grep -P "apptools|traits "
apptools             4.5.0-5         enthought/free
traits               6.1.1-1         enthought/free

Here's a small example:

Initially, the preferences file contains:

# File: myprefs.ini
[my_section]
things = "['one', 'two']"

Then, we run a script that updates the things preference list:

from apptools.preferences.api import Preferences, PreferencesHelper
from traits.api import Int, List, Str

class MyHelper(PreferencesHelper):
    preferences_path = 'my_section'
    things = List(Str)

prefs = Preferences(filename='myprefs.ini')
helper = MyHelper(preferences=prefs)
helper.things.append('another thing!')
prefs.save()

After the script is run, the preferences file looks like:

# File: myprefs.ini
[my_section]
things = "['one', 'two']"
things_items = "TraitListEvent(index=2, removed=[], added=['another thing!'])"

As far as I can tell, the culprit is this block in the PreferencesHelper class:

def _anytrait_changed(self, trait_name, old, new):
""" Static trait change handler. """
# If we were the one that set the trait (because the underlying
# preferences node changed) then do nothing.
if self.preferences and self._is_preference_trait(trait_name):
self.preferences.set('%s.%s' % (self._get_path(), trait_name), new)
return

Document apptools.type_registry

This is a comparatively recent addition to apptools. It should be documented with examples of the problems it is idesigned to solve.

state-pickler.py is getting blank lines added when doing pip install

Same problem as #79: state-pickler.py is getting a blank line added after ever line when doing a pip install. Other files don't seem to have this problem, and doing a manual .zip folder download doesn't seem to have this problem either. This is causing multiple syntax errors and preventing use of mayavi without manually adjusting the state-pickler.py file.

Test suite modifies a tracked file

When I run the test suite under Python 3.8.1 (on macOS, in a venv), it modifies the file apptools/preferences/tests/example.ini:

(apptools-3.8) mirzakhani:apptools mdickinson$ git diff
diff --git a/apptools/preferences/tests/example.ini b/apptools/preferences/tests/example.ini
index 100dc6e1..c535635c 100644
--- a/apptools/preferences/tests/example.ini
+++ b/apptools/preferences/tests/example.ini
@@ -3,7 +3,7 @@ bgcolor = blue
 width = 50
 ratio = 1.0
 visible = True
-description = 'acme ui'
+description = acme ui
 offsets = "[1, 2, 3, 4]"
 names = "['joe', 'fred', 'jane']"
 

Steps to reproduce, from a clean clone:

  • Create a Python 3.8.1 venv, and activate it (python3.8 -m venv ~/.venvs/apptools-3.8, source ~/.venvs/apptools-3.8/bin/activate
  • Install dependencies: pip install nose numpy tables pandas
  • Install apptools: pip install -e .
  • git status at this point shows that the working tree is clean
  • Run tests: nosetests .
  • git status now shows modifications to examples.ini.

Add common testing utilities?

[From discussion in enthought/envisage#188]

There are a number of testing utilities that are being replicated from repository to repository (usually with minor API changes each time). It would be good to standardise these and put them in a common place.

The two things that sparked this discussion were (a) utilities for catching and testing logs (though with Python 3, the standard library unittest has this capabiilty), and (b) utilities for capturing output streams.

Here's the relevant code. For context, see: https://github.com/enthought/envisage/blob/54bda86ca195b5b6d59b72a037d58c4bc01f3ff9/envisage/plugins/ipython_kernel/tests/test_internal_ipkernel.py#L33-L108

# Machinery for catching logged messages in tests (both for testing
# the existence and content of those messages, and for hiding the
# logger output during the test run).

class ListHandler(logging.Handler):
    """
    Simple logging handler that stores all records in a list.

    Used by catch_logs below.
    """
    def __init__(self):
        logging.Handler.__init__(self)
        self.records = []

    def emit(self, record):
        self.records.append(record)


@contextlib.contextmanager
def catch_logs(logger_name, level=logging.WARNING):
    """
    Temporarily redirect logs for the given logger to a list.

    Also allows temporarily changing the level of that logger.
    """
    logger = logging.getLogger(logger_name)
    handler = ListHandler()
    old_propagate = logger.propagate
    old_level = logger.level

    logger.addHandler(handler)
    logger.propagate = False
    logger.setLevel(level)
    try:
        yield handler.records
    finally:
        logger.setLevel(old_level)
        logger.propagate = old_propagate
        logger.removeHandler(handler)


@contextlib.contextmanager
def capture_stream(stream, callback=None):
    """
    Context manager to capture output to a particular stream.

    Capture all output written to the given stream. If the optional
    callback is provided, call it with the captured output (which
    will be a bytestring) when exiting the with block.

    Parameters
    ----------
    stream : Python stream
        For example, sys.__stdout__.
    callback : callable
        Callable of a single argument.
    """
    stream_fd = stream.fileno()

    with tempfile.TemporaryFile() as new_stream:
        old_stream_fd = os.dup(stream_fd)
        stream.flush()
        os.dup2(new_stream.fileno(), stream_fd)
        try:
            yield
        finally:
            stream.flush()
            os.dup2(old_stream_fd, stream_fd)
            os.close(old_stream_fd)

        new_stream.flush()
        new_stream.seek(0)
        captured = new_stream.read()

    if callback is not None:
        callback(captured)

Release 4.5.0 checklist

  • Review open PRs
  • Review open issues for anything else that should go into this release.
  • Update changelog
  • Make release branch
  • Bump version on release branch (via PR against release branch)
  • Bump version on master for continued development
  • Testing! (Create sdist, install from sdist, check tests pass.)
  • Tag
  • Testing!
  • Update release information on GitHub
  • PyPI upload
  • More testing!
  • Build and upload documentation.
  • Buildsystem issue for package update
  • Bring any necessary changes back into master Nothing to do.

After eggs are built for EDM:

  • One more round of testing with the EDM eggs
  • Announce the release (Slack, portal, ets-users)

Deprecate use of global preferences.

I suggest deprecating use of the global preferences (via the get_default_preferences and set_default_preferences functions, and implicitly via the three-argument form of bind_preference). This mutable global default complicates testing, and leads to code with spooky action-at-a-distance.

Update the changes.txt

It would be nice to populate the CHANGES.TXT file with all the changes that have happend between version 4.2.1 and version 4.4.0

Remove spickle entirely

The apptools.persistence.spickle module does not work on Python 3.4. We either should port it so it does or remove it entirely if no one is using it.

invalid syntax after updating to python 3.7.1

After I upgrade to Python 3.7.1, when "from mayavi import mlab", it throws out "Invalid syntax" error from \apptools\persistence\state_pickler.py
line 1210, 1456, 2001
I think it is caused by when you wrap the line with "", the following line is blank, and that throws out an error with the latest Python 3.7.

Consider splitting into UI and non-UI pieces

Some of the parts of Apptools provide fundamental application services for any type of application (eg. preferences, persistence, naming, logging), but others are tightly tied to GUI features (preference UI, logging UI, undo/redo, scripting).

There may be a point to providing two packages: a low-level set of tools which depends only on Traits (and maybe, optionally, Envisage), and a high-level set of tools and interfaces to the low-level tools for use in GUI applications.

For backwards compatibility, the high-level toolkit should retain the Apptools name and at least for a while should import the low-level tools into the namespace.

File from apptools.io should implement os.PathLike

If we were to add a __fspath__ method and register the class with os.PathLike (where available) it would mean that File objects could be used in a similar way to pathlib.Path objects throughout Python.

As a secondary consideration, using a pathlib path object instead of a string as the source of truth for the File class would simplify a lot of the logic; it would probably make sense to also duplicate the pathlib.Path API (alongside the current API).

Decide fate of apptools.naming

This is an implementation of the Java Naming and Directory Interface - or at least the naming part of that - with specific implementations for a hierarchy of Python objects and for file system stores. It is used by Mayavi, but possibly only as part of the Wx backend.

It is intended to provide a standard API for hierarchical namespaces that standard interfaces can then build on top of, but I have a suspicion that at least some of the code that duplicates the Java APIs is over-engineered for Python (eg. the InitialContextFactory object feels very much like it could just be a callable).

If it is to be kept, then there are some improvements that should be made:

  • it has its own adapter system; this should be converted to use standard Traits adaptation
  • the pyfs_context seems of limited utility for Enthought and insecure by default (since it uses pickles); a JSON-backed version might make more sense if it is needed at all
  • perhaps split out implementations from abstract/base classes
  • separate out the UI components and fix them up (see #138)
  • generally clean-up the codebase.

Document apptools.lru_cache

The apptools.lru_cache is a comparatively recent addition to the apptools suite. It provides a traitified version of an LRU cache. While this is a fairly well-understood concept, it should have at least minimal documentation and examples of use.

Remove apptools.type_manager?

The apptools.type_manager module has a lot of overlap with the Traits adaptation system since the latter gained the ability to have multiple adapter registries.

It is, however, used by apptools.naming which is in turn used by Mayavi, so we can't simply remove.

The correct way forward is probably to investigate whether apptools.naming can use Traits adaptation, and whether Mayavi uses the type manager's objects directly via the naming module

Remove LRUCache from apptools

[Update] A decision has been made to remove LRUCache from apptools. See comment further down the thread - #91 (comment)

Python 3.x provides lru cache via the functools stdlib package, which is available on Python 2.x as the backported functools32 package.

I don't know what the differences between the LRUCache that apptools provides and how it is different from the one from functools. I am also not sure who is using LRUCache from apptools.

Note that if we do choose to remove the module/class, the next release will have to be a major release.

See https://github.com/enthought/apptools/blob/master/apptools/lru_cache/lru_cache.py

Decide fate of apptools.help

This is a workbench/envisage plugin for contributing links to external documentation and demos. It uses preferences for pointing to directories which contain documentation and demo code.

It may make sense to keep for applications still using workbench; it may also make sense to create a Tasks version as well.

It may be used by Mayavi, but that is not clear.

StopIteration error with test_iter_groups test under Python 3.8

I'm seeing the following with Python 3.8 (it probably occurs under Python 3.7 too):

======================================================================
ERROR: apptools.io.h5.tests.test_file.test_iter_groups
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/tables/misc/proxydict.py", line 62, in itervalues
    raise StopIteration
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.8_apptools/build/apptools/io/h5/tests/test_file.py", line 429, in test_iter_groups
    assert set(n.name for n in group.iter_groups()) == set(['subgroup'])
  File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.8_apptools/build/apptools/io/h5/tests/test_file.py", line 429, in <genexpr>
    assert set(n.name for n in group.iter_groups()) == set(['subgroup'])
  File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.8_apptools/build/apptools/io/h5/file.py", line 434, in <genexpr>
    return (_wrap_node(g) for g in self._h5_group._v_groups.itervalues())
RuntimeError: generator raised StopIteration

----------------------------------------------------------------------
Ran 401 tests in 1.491s

FAILED (SKIP=1, errors=1)

Allow unbinding of preferences.

There's currently no easy way to unbind preferences that were bound with bind_preference. There are some situations where it would be useful to be able to do so. One example is during testing, where one sometimes wants to swap out the current file-backed preferences for a simpler preferences object in order to avoid the test writing to the preferences file unnecessarily.

permissions recommends namespace packages that don't work

apptools.permissions in several _*_default() methods tries to import a class from an apptools.permissions.external package and then defaults to loading the default class from apptools.permissions itself. The documentation recommends that you make an apptools.permissions.external namespace package with your custom implementations if you want to use them. We haven't supported namespace packages since it was enthought.permissions.

We could fix up the _*_default() methods and the documentation to recommend the right way to do things. I'm not really sure why such an inflexible-yet-convoluted scheme was put in place at all, but obviously, we aren't using this code. Should we just deprecate it?

http://stackoverflow.com/questions/33126823/python-enthought-apptools-with-merging-namespace/33136515#33136515

StatePickler cache is broken: can result in data corruption

The StatePickler uses the hash function hash to generate a key for its object cache, at least for hashable objects. Without an extra equality check, this is broken, and leads to different objects with the same hash being treated as the same object.

Example failure resulting from this:

>>> from apptools.persistence.state_pickler import *
>>> loads_state(dumps([(-1, -1), (-2, -2), (-3, -3)]))
[(-1, -1), (-1, -1), (-3, -3)]

Here the error occurs because the tuples (-1, -1) and (-2, -2) have the same hash.

Remove appscripting subpackage

There are two application scripting systems in AppTools. Mayavi uses the apptools.scripting package. No Enthought application has used apptools.appscripting in the last 10 years or so. Therefore apptools.scripting should be removed.

This removal should probably occur in the next major release, with any third party users encouraged to use apptools.scripting.

Documentation for apptools naming

Apptools naming is complex and almost completely undocumented. It is used by Mayavi, it cannot be ignored as not to be used, but without documentation it is not clear what the module is intended to be used for.

It looks like this may be a Python implementation of the Java Naming and Directory Interface.

Decide fate of apptools.io

This submodule provides a traited File object that provides properties and methods for common file path manipulation operations. Much of this functionality is provided in Python 3 by the pathlib module, and it is not clear what precise benefits this provides, other than notifications of state change. It may be that this is not needed any more. Or it may be that there is some extra functionality which is part of the class, but which could be better handled by using pathlib objects for the duplicated functionality and the File class for everything novel.

There is also apptools.io.h5 which wraps h5py with a dictionary-style mapping. This may end up being superseded by Zarr and similar libraries; but it is likely this code is used by various Enthought applications.

Decide fate of apptools.template

The apptools.template package is designed to provide a system for configuring traits classes and instantiating them according to the template. This is motivated by, for example, allowing a user to create templates to style Chaco plots and then use those style choices when creating the actual plot instances.

The template objects are also designed to help with serialization and deserialization, allowing the configuration of application state to be separated from the data sources when serializaing.

This is potentially a very useful set of functionality, but it may not be worth preserving.

Or, alternatively, apptools is not the place for it, and it really needs to live in Chaco until a wider use for it is found.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.