omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    tinysync

    Pythonista
    2
    4
    1353
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • mikael
      mikael last edited by

      I know this is not very Pythonic, as it makes things more implicit than explicit, but I wanted to see how far I could push this approach of making things "just happen" without the developer always having to worry about the boilerplate.

      So, lots of "magic" around simple dict/list data structures:

      Magic 1 - React to changes

      from tinysync import track
      
      data = { 'a': [1, 2], 'b': [3, 4] }
      data = track(data, change_callback=my_func)
      

      With this, my_func is called with change details whenever you make any changes to the data (which can be a combo of dicts, lists and sets).

      Not sure how terribly useful this is as a stand-alone capability - maybe for updating the UI every time the data changes?

      Magic 2 - Persist data

      data = track(data, 'config.yaml')
      

      With this, all further changes to the data are saved as YAML into a file called 'config.yaml'. If there already is a file, data is initialized from its contents.

      This I have found quite useful as a no-fuss persistence of configurations and similar. There is also support for other file formats and DBMs.

      Magic 3 - Thread safety

      with data:
          data['b'][1] = data['a'][0]
      

      If you have multiple threads and need to make complex changes to the data, using the structure itself as a context manager locks it, making other threads wait.

      Magic 4 - Versions

      from tinysync import track, handler
      
      data = track({}, history=True)
      h = handler(data).history
      data['a'] = 5
      data['a'] = [1, 2]
      len(h) # 2
      h.undo()
      h.active # 1
      data['a'] # 5
      h.redo() # 0
      data['a'] # [1, 2]
      

      Since we react to changes, it is natural to store deltas and play them backwards and forwards. This could be a fit for some kind of a configuration editor, I think.

      Magic 5 - Transactions

      from tinysync import track, atomic
      
      data = track(data, 'config.yaml')
      
      with atomic(data):
          del data['option2']
          data['option1'] = True
      

      With the atomic context manager, all the changes are applied, or none. In the example above, if del throws an error, data is not left in an inconsistent state, and nothing is written to file. Also, if you use versions, all the changes within the context manager are treated as one revision.

      Dangerous Magic 6 - Dot access

      from tinysync import track, dot_on
      
      dot_on()
      data = track({
          'options': {
              'option1': 'value',
              'option2': 'value
          }
      })
      print(data.options.option1)
      

      For those who like this option, despite the additional potential confusion to the readers of the code.

      Implementation of all of the above relies heavily on the dictdiffer package, and is not much concerned with performance. Code on github is quite beta.

      cvp 1 Reply Last reply Reply Quote 2
      • cvp
        cvp @mikael last edited by

        @mikael said:

        Magic 3 - Thread safety

        Didn't know. Thanks for the info, useful

        mikael 1 Reply Last reply Reply Quote 0
        • mikael
          mikael @cvp last edited by

          @cvp said:

          @mikael said:

          Magic 3 - Thread safety

          Didn't know. Thanks for the info, useful

          This reads like I gave you the impression that regular dicts work this way, but no, you need the tinysync magic version.

          cvp 1 Reply Last reply Reply Quote 0
          • cvp
            cvp @mikael last edited by

            @mikael I had understood, not as usual 😀

            1 Reply Last reply Reply Quote 0
            • First post
              Last post
            Powered by NodeBB Forums | Contributors