Giter VIP home page Giter VIP logo

Comments (9)

itamarst avatar itamarst commented on May 18, 2024

Oops. Will fix for next release.

from crochet.

cscutcher avatar cscutcher commented on May 18, 2024

It might be slightly tangential to this issue, as it may be better to avoid importing the module to be installed during setup, even if it does work, but in general I'm a bit oversensitive to any non-trivial class being initialised at import time that doesn't have to.

So;

...
_main = EventLoop(reactor, register, startLoggingWithObserver,
                  _watchdog, reapAllProcesses)
setup = _main.setup
no_setup = _main.no_setup
run_in_reactor = _main.run_in_reactor
wait_for_reactor = _main.wait_for_reactor
retrieve_result = _store.retrieve

# Backwards compatibility with 0.5.0:
in_reactor = _main.in_reactor
DeferredResult = EventualResult

in __init__.py makes me a little nervous.

I can see that it adds some convenience but personally I'd rather see initilisation of an EventLoop happing manually, triggered by client code after import, rather than during. Otherwise I'm fearful of other unintended import sideeffects in the future.

@itamarst If you don't mind me asking I'd be really interested to know if doing all this setup in import time was deliberate decision you'd be un-inclined to change or if it was an evolution that you might consider changing in the future.

from crochet.

itamarst avatar itamarst commented on May 18, 2024

Creating an EventLoop instance has no side effects. It's just there to help make unit testing easier by minimizing module-level state. The actual things that have side effects are calling setup() (and to lesser extent no_setup()).

So, nothing actually happens when you import; it creates an object but that's all.

from crochet.

itamarst avatar itamarst commented on May 18, 2024

See also http://blog.futurefoundries.com/2013/04/unittesting-without-patching.html and read some of the unit tests to get a sense of why it's structured this way.

from crochet.

cscutcher avatar cscutcher commented on May 18, 2024

Thanks for the reply and link. You're probably right but let me have another go at explaining my logic in the hope that I seem less silly by the end of it.

First of all I don't think I disagree with what you're saying in the article. Equally I'm not saying that it'll cause problems immediately, more that it could cause problems down the line.

It's not that I don't like the idea of storing the state in a class, or even where it lives but that I don't like that it's initialised and installed transparently at import time.

As a client of the module I don't like things happening when I'm not expecting them too, especially if I have no way to prevent them happening once I spot something that is.
I'm sure at the moment it's relatively harmless, as I'm sure you're ensuring that anything that happens in the init doesn't have unexpected sideeffects, but in the future it's easy to imagine code sneaking into initialiser of EventLoop or indeed anything it initilialises that does have sideeffects, especially if its third party code.

I've had this happen to me a few times and bite me in the arse. Here's an unnecessary, hideously contrived, example which is vaguely similar to a problem I've seen before.

# my_awesome_module/__init__.py
_main = StateContainer()
...
# elsewhere
class StateContainer(object):
    def __init__(self):
        self.some_innocent_state = ContainerObjectFromThirdParty()
...
# in third-party module
class ContainerObjectFromThirdParty(object):
    def __init__(self):
        self.default_error_message = get_translated("default")
...
def get_translated(message):
   open_translation_config_file(...)
   ...
   explode_planet()
   ...
   return translated_message

So I as a user I import my_awesome_module in some interesting environment and all of the sudden I've got unexpected file reads and exploded planets.

What's more it's often difficult to back out of this trap too, especially if you've trained the the user to write the client code assuming magic is happening to set stuff up and all the have to do is import and go, because you'll either have to do more trickery or break backwards compatibility.

My preferred design is have anything like that holds module-state start of at None in the module definition. Then after import someone deliberately calls some setup/initialising function and off they go. It's a little less convenient perhaps but I'd rather have transparency in this case.

Anyway if I haven't got you agreeing with me I hope I at least seem less nuts :-)

from crochet.

itamarst avatar itamarst commented on May 18, 2024

Well, I do have setup() and no_setup() hooks for users. I'm not going to worry about it for now, since it's very theoretical (EventLoop.__init__ deliberately does basically nothing). Maybe next time I wrote some code with this pattern.

from crochet.

itamarst avatar itamarst commented on May 18, 2024

I was wrong about no side-effects; see issue #19.

from crochet.

cscutcher avatar cscutcher commented on May 18, 2024

Have you thought about how you plan to fix the pip install issue in the short term? I could have a go and get this issue closed.

from crochet.

itamarst avatar itamarst commented on May 18, 2024
  1. Move __version__ to crochet/_version.py, and have __init__.py import it from there.
  2. setup.py can then exec() the contents of crochet/_version.py to get the version information.

from crochet.

Related Issues (20)

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.