I would like to hear arguments for or against a plan I am considering.  I have a large network of nodes each of which has vector-valued properties.  Accessing these properties (read or write) requires a timestamp.Plan A: pass the timestamp to every method that will access properties (and every method calling those methods, etc.)Plan B: have a global variable that is a context stack.  Using a context manager, when a context is entered, push a new timestamp onto the stack; pop it on exit.  The property access will use the context stack to provide the timestamp.Pros to plan A: multiple networks can run in parallel easily (although I don't need multiple networks to run).  It is easy to see all of the dependencies because there are no hidden dependencies.Pros to plan B: the code that operates on properties is simpler.  It can just use member access to read and write: self.b[2] += self.a instead of self.b.increment(context, self.a, 2).Which plan should I choose?  Did I miss any pros and cons?
Is a global context stack a code smell?
design;globals
B is harder to parallelize, but you're not doing that.  So what, right?  Nope, it's still a Bad Thing, and here's why:That extra parameter you're trying to avoid is there for a reason.  It indicates a data dependency which might not otherwise be obvious.  This makes your code easier to reason about after time has passed and you are no longer familiar with it.  These dependencies simplify refactoring and development of new features, by reducing the amount of spooky action at a distance you have to worry about.  If something is not a parameter of a given function, then changing that thing should not affect that function.  If you want to move or copy a function call to a different part of your codebase, you need only move or copy all of its parameters over to wherever you want to call it from; you don't have to fiddle with some global state to make it behave properly.  If you want to coalesce two functions, you need only take the union of their parameters and watch for interference among those parameters; you do not need to worry about how they interact with globals.  Every form of refactoring is easier with no globals in play.Now, a certain amount of global state may be unavoidable, for just about every language other than Haskell, which you are clearly not using.  For example, most forms of I/O are global operations since they affect the outside world.  Unix has a number of global process parameters that can be difficult to totally avoid (e.g. the current directory, the umask, etc.).  But that does not excuse going around inventing new kinds of global state.  (Mutable) global state is always guilty until proven innocent.It may well be that there is a more fundamental design issue with this context object.  Perhaps you could make it an instance variable, so that the properties have access to it and you can write simpler property-driven code.  But at that point, you probably want to break it down into its constituent parts, rather than just having a single self.context variable.  self is supposed to be your bag of random context; having a self.context doesn't make much sense.  Or perhaps there is some more basic issue which I cannot see without knowing more about your codebase.