0

I'm adding attributes to a module at runtime using the following inside a loop:

this_module = sys.modules[__name__]
setattr(this_module, attr_name, attr_value)

When I call print dir(this_module) from the module, it shows the attributes. Great!

When I import the module and try to use the attribute in a decorator, an AttributeError exception keeps getting thrown. To debug, I called dir() on the imported module and none of the attributes added on the fly are listed!

I even added the attribute names to __all__ for the import * and still nothing!

Any ideas would be great. Also, please let me know of any terminology I could be missing. I wasn't able to find an answer searching Google.

--

Per a suggestion by Kevin, I added a dictionary to my Flask application (instead of his suggestion of top-level, just for ease of testing) and added those attributes to it:

app.security = dict()

In the loop:

app.security[attr_name] = attr_value

In the module where the decorator is used ('time_entry' is an attribute name and it holds a class instance):

@app.security['time_entry'].need()

When I try to start the server, I now get this error:

    @security["time_write"].require()
             ^
    SyntaxError: invalid syntax
Logan Bibby
  • 1,167
  • 1
  • 10
  • 31
  • 1
    Why are you doing this instead of just using a top-level dictionary? – Kevin Feb 28 '15 at 04:35
  • Are you sure that the decorator is called _after_ the attribute has been set? Also you could try doing `global attr_name` followed by `attr_name = attr_value`. – Cristian Ciupitu Feb 28 '15 at 04:37
  • @Kevin: Can't use a dictionary as a decorator, though, right? I have to be able to call it in a decorator. – Logan Bibby Feb 28 '15 at 05:01
  • @CristianCiupitu: The attribute names and values are created on the fly from a database. I don't think it'd work in this situation. – Logan Bibby Feb 28 '15 at 05:02
  • You can't use a module as a decorator either. A decorator can equally well access a dictionary or a module. – Kevin Feb 28 '15 at 14:50
  • @Kevin: I tried. It said the opening brace was invalid syntax. Unless I'm missing a proper was of calling it. – Logan Bibby Feb 28 '15 at 14:55
  • You're going to need to show us your code if you want us to help you. And why are you trying to "call" a dictionary? Dictionaries (and modules) are not callable objects. Functions are callable. Methods are callable. Classes are (basically) callable. – Kevin Feb 28 '15 at 15:07
  • @Kevin: Sorry, I meant just using it in a decorator... The line (as it stands now) is `@security['time_write'].require()`. As far as I know, syntactically, there's nothing wrong with using a dictionary in a decorator. – Logan Bibby Feb 28 '15 at 15:13
  • @Logan: The decorator syntax consists of a [dotted name, possibly called as a function](https://docs.python.org/2/reference/compound_stmts.html#grammar-token-decorator) (**edit**: [Guido on this](https://mail.python.org/pipermail/python-dev/2004-August/046711.html)). But you can just do `require = security['time_write'].require` on the line before. – Kevin Feb 28 '15 at 20:08

1 Answers1

0

I've created a workaround for my particular problem. It's not a solution and I still plan on investigating it further once this project is finished.

I created a dummy class and then set an attribute with an instance of it in my Flask application.

class Security: pass
app.security = Security()

Then, I set the attributes directly to the Security class:

setattr(app.security, attr_name, attr_value)

Again, it doesn't resolve why those module-level attributes I was creating at runtime weren't being imported. I'll come back and edit this once I have the answer to that question.

Logan Bibby
  • 1,167
  • 1
  • 10
  • 31