-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Late includes #1650
Late includes #1650
Conversation
I'm in favor of the concept, not so sure about the syntax. One change (which would be more invasive) would be to order the includes and declarations in the same order that they occur in the file, e.g.
This also has pros and cons, but might be more flexible. |
Like I said, I care about the feature, not the syntax. Maybe a new keyword like
but that will require changes to the parser.
Two obvious "cons" are that it will be not so easy to implement (certainly beyond what I could do) and that it has potential to break existing code. |
Is there a clear reason why the includes must come before the declarations by default? Meaning, does this solve a new use case in addition to an existing one, or is there really just one use case that was solved incorrectly before? |
Obviously yes: if the header file defines a new type that you want to use in Cython. This is a very common use case. |
On the other hand, needing to include code after Cython's declarations is not a common usecase. I'd like to see at least one more example where it'd be useful. (I'd also like more intuitive syntax, but that's a smaller issue.) |
So you want me to invent a new use before you want to merge this PR? I guess that some cases where currently a separate C file is added to the sources (i.e. something like In general, "late includes" are needed whenever some C code needs access to variables defined by Cython. I think that's a reasonable thing to do, even if it's uncommon. |
There is another use case at https://trac.sagemath.org/ticket/21459#comment:22 |
I like this idea and can definitely see where it would be useful. As to the bikeshed, I like the additional syntax |
I ran into this again while working on https://trac.sagemath.org/ticket/23022 (I have now solved that ticket differently which doesn't require this PR). In general, this issue occurs when implementing functions in C using |
Is there a specific reason for the existing default behavior? That is, is there any reason the include couldn't just come after the Cython defines by default? |
The same question has been asked above and answered in #1650 (comment) |
Oops, sorry. Got it. |
Allow me to ask for another ping on this PR. This is genuinely useful... |
I'm not convinced that this being "genuinely useful". Even |
I think it's not so relevant whether it is common or not. The question is whether is it sensible and useful. And maybe it is not so common because it is hard to make it work currently. People use what is documented and what works.
I personally dislike that solution because it is more complicated: it requires 2 manually-written C files (a file with the implementation to be added as extra source file and a file with the declarations to be used with Also keep in mind that (in my use cases at least), the C files make heavy use of macros: if it would be plain functions, I might as well implement them in Cython directly. This might make it even more complicated to untangle in a Anyway, if the official Cython recommendation for situations like these is to use |
If there is something we can do to ease that setup, I'd be happy to hear about it. It's definitely more general than what this pull request gives. Improvements to the docs are also always welcome.
Plus Thank you for the insightful discussion and your continuous efforts. I really appreciate it. |
I don't agree but at least it's better than keeping a PR open forever. I hope that this implies that Cython will add support for this two-file way of compiling in cases where it doesn't properly work. For example, I already see one potential issue: if you want this to work with distributed
The whole point of this PR is that this doesn't always work. At least it does not work if the |
It has access to them, if you declare them as
This is best handled with a properly exported C-API, and there is support for that via the normal |
Please elaborate, I have no idea what you mean with this. My scenario would be as follows: I have a
Both PR #1654 dealt with automatically finding the |
... in which case it would not not be a .pxd file but an extension module (.pyx), which would then export a C-API via its .pxd file. |
I think it means that compiling For the above example, the The resulting IMO the above functionality would be akin to a circular import in regular python modules. Module A uses function from module B, module B uses function from module A. The solution is to import neither but use a third module to 'link' them so that A and B import from C and not each other. The same applies in C. When the C code is actually cython generated it gets more complicated but trying to make circular imports 'work' is prone to other issues. What happens when the |
No, I really mean what I wrote: a |
Can setuptools compile a dynamic library? I don't think so, but feel free to prove me wrong... |
Yes.
Ok, but then we're back to the normal case of a .pxd file that declares extern code from a .h file (or .c, if you prefer). Why should that not work? You fixed it in #1654, right? If it's a separately installed package, you really cannot expect the code over there to be able to get access to your own code in your local package. That seems like a really troublesome setup with way too tight coupling between packages. |
Can do better than that, here's a real world example :) |
Care to elaborate? At least provide a link to documentation or sources? I found these two SO posts but they don't have an answer either:
Both have answers, but they are about extension modules, not dynamic libraries.
Again, that's an extension module, not a dynamic library. |
Exactly because of this PR that you closed! That works if Cython code wants to access the C code, but not if the C code wants to access the Cython code. |
Are you referring to compiling system libraries via setuptools? Then no, but why should it? It only needs access to the In the case of wheels, there is functionality to correctly install dependent shared libraries so they are bundled together (auditwheel and delocate for linux/osx respectively). That's really a link time job rather than a compile time job, IMO. |
I thought that is what you meant with your answer, but it seems that I misunderstood. Anyway, I know how to create extension modules with Cython, but that seems besides the point. |
Let me elaborate on the dynamic library vs. extension module: with dynamic linking, the symbols (variables/functions) are automatically there and can be used by C code without any special action. With extension modules, you can import stuff but that requires an explicit action. And I wouldn't know how to do that: as far as I know, Cython has no way to define extra code in the So the option that I was pursuing in this PR was to let Cython do the import in the usual way. But currently, I have no way to access those imports from C code. |
Example: https://github.com/scoder/lupa/blob/lupa-1.5/setup.py#L179 |
I think we should move this discussion to the cython-users mailing list. The issue tracker (and especially a pull request) is the wrong place to discuss this. I closed this PR because I think that the problem it solves is way to narrow and specific to merit being a feature. There are other ways to solve the general problem. |
I'm happy with one least one way :-) I'll write to cython-users, please answer there. |
Since most opposition from @robertwb to this PR was about the syntax, maybe I could salvage it by not using any explicit syntax. Instead, depending on the contents of the |
New attempt at #1896 |
This is now tracked in #2079. |
This pull request adds support for a late
#include
. My proposed syntax is to add a leading pipe to the filename:For this
cdef extern
block, Cython will generate the#include
statement after its own variable declarations. So it can be used if the C code inspam.h
needs to refer to Cython variables.cysignals
has a use-case which is currently "solved" by some ugly hack involving.pxi
files (for which I need #483). If this pull request is accepted,cysignals
would no longer need to rely on.pxi
files: sagemath/cysignals#49Of course, there are plenty of bikeshedding opportunities for the syntax, but I care about the feature, not the syntax. I chose the leading pipe because it is unlikely to occur in actual filenames. (Also: think of the pipe as "piping" the Cython variables into the header file).